using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Drawing.Design; using System.Drawing.Drawing2D; using System.Windows.Forms; using DevComponents.DotNetBar.SuperGrid.Primitives; using DevComponents.DotNetBar.SuperGrid.Style; using DevComponents.SuperGrid.TextMarkup; namespace DevComponents.DotNetBar.SuperGrid { /// /// Represents a layout of column headers /// [TypeConverter(typeof(BlankExpandableObjectConverter))] public class GridColumnHeader : GridElement { #region Constants private const int SeparatorWidth = 2; private const int ImageCacheSize = 8; #endregion #region Static data private static object _lastSelectedItem; #endregion #region Private variables private GridColumnCollection _Columns; private ColumnGroupHeaderCollection _GroupHeaders; private HeaderArea _HitArea; private object _HitItem; private HeaderArea _LastHitArea; private object _LastHitItem; private GridColumn _ResizeColumn; private int _MouseDownDelta; private HeaderArea _MouseDownHitArea; private object _MouseDownHitItem; private Point _MouseDownPoint; private MouseButtons _MouseDownButtons; private bool _DragSelection; private bool _DragStarted; private bool _Reordering; private bool _Resizing; private int _ResizeWidth; private int _MinRowHeight; private int _RowHeight; private GridColumn _SeparatorColumn; private bool _SeparatorIsRight; private FloatWindow _HeaderFw; private FloatWindow _SeparatorFw; private int _OrderTextOffset; private int _SelectAllCount; private ColumnHeaderRowVisualStyles _EffectiveRowHeaderStyles; private int _StyleUpdateCount; private bool _ShowHeaderImages = true; private Image _AscendingSortImage; private int _AscendingSortImageIndex = -1; private Image[] _AscendingSortCacheImages = new Image[ImageCacheSize]; private Image _DescendingSortImage; private int _DescendingSortImageIndex = -1; private Image[] _DescendingSortCacheImages = new Image[ImageCacheSize]; private Alignment _SortImageAlignment = Alignment.NotSet; private Image _FilterImage; private int _FilterImageIndex = -1; private Image[] _FilterCacheImages = new Image[ImageCacheSize * 2]; private ImageVisibility _FilterImageVisibility = ImageVisibility.Auto; private Alignment _FilterImageAlignment = Alignment.NotSet; private FilterPopup _FilterMenu; private bool _LockedColumn; private bool _ShowFilterToolTips = true; private bool _ShowToolTips = true; private bool _ShowGroupColumnHeaders = true; private bool _AutoApplyGroupColors = true; private string _RowHeaderText; #endregion #region Internal properties #region Columns internal GridColumnCollection Columns { get { return (_Columns); } set { _Columns = value; } } #endregion #region RowHeaderBounds internal Rectangle RowHeaderBounds { get { GridPanel panel = GridPanel; if (panel != null) { Rectangle r = Bounds; r.Width = panel.RowHeaderWidthEx; return (r); } return (Rectangle.Empty); } } #endregion #region SelectAllCount internal int SelectAllCount { get { return (_SelectAllCount); } set { _SelectAllCount = value; } } #endregion #endregion #region Public properties #region AscendingSortImage /// /// Gets or sets the Ascending sort image /// [DefaultValue(null), Category("Appearance")] [Description("Indicates the Ascending sort image.")] public Image AscendingSortImage { get { return (_AscendingSortImage); } set { if (_AscendingSortImage != value) { _AscendingSortImage = value; OnPropertyChangedEx("AscendingSortImage", VisualChangeType.Render); } } } #region GetAscendingSortImage internal Image GetAscendingSortImage(GridColumn column) { if (_AscendingSortImage != null) return (_AscendingSortImage); if (_AscendingSortImageIndex >= 0) { ImageList imageList = GridPanel.ImageList; if (imageList != null && _AscendingSortImageIndex < imageList.Images.Count) return (imageList.Images[_AscendingSortImageIndex]); } return (GetAscendingSortImageEx(column)); } #region GetAscendingSortImageEx internal Image GetAscendingSortImageEx(GridColumn column) { StyleState state = GetStyleState(column, column.IsSelected); Image cacheImage = _AscendingSortCacheImages[(int)state]; if (cacheImage == null) { int width = Dpi.Width5; int height = Dpi.Height3; if ((width % 2) == 0) width++; Rectangle r = new Rectangle(0, 0, width, height); Image image = new Bitmap(width, height); using (Graphics g = Graphics.FromImage(image)) { g.SmoothingMode = SmoothingMode.AntiAlias; using (GraphicsPath path = new GraphicsPath()) { Point pt = new Point(r.X + r.Width / 2, r.Top); Point[] pts = { pt, new Point(r.Right - 1, r.Bottom - 1), new Point(r.Left, r.Bottom - 1), pt }; path.AddLines(pts); ColumnHeaderRowVisualStyle style = GetEffectiveRowHeaderStyleEx(state); Color color = style.SortIndicatorColor; if (color.IsEmpty) color = Color.Black; using (Brush br = new SolidBrush(color)) g.FillPath(br, path); using (Pen pen = new Pen(color)) g.DrawPath(pen, path); } } _AscendingSortCacheImages[(int)state] = image; cacheImage = image; } return (cacheImage); } #endregion #endregion #endregion #region AscendingSortImageIndex /// /// Gets or sets the Ascending Sort Image index /// [Browsable(true), DefaultValue(-1)] [Category("Appearance"), Description("Indicates the Ascending Sort Image index.")] [Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] [TypeConverter(typeof(ImageIndexConverter))] public int AscendingSortImageIndex { get { return (_AscendingSortImageIndex); } set { if (_AscendingSortImageIndex != value) { _AscendingSortImageIndex = value; OnPropertyChangedEx("AscendingSortImageIndex", VisualChangeType.Layout); } } } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] private void ResetAscendingSortImageIndex() { _AscendingSortImageIndex = -1; } #endregion #region AutoApplyGroupColors /// /// Gets or sets whether Group Header color properties /// (ie. Background and TextColor) are automatically /// applied to group Column Headers. /// [DefaultValue(true), Category("Appearance")] [Description("Indicates whether Group Header color properties (ie. Background and TextColor) are automatically applied to group Column Headers.")] public bool AutoApplyGroupColors { get { return (_AutoApplyGroupColors); } set { if (_AutoApplyGroupColors != value) { _AutoApplyGroupColors = value; OnPropertyChangedEx("AutoApplyGroupColors", VisualChangeType.Render); } } } #endregion #region Bounds /// /// Gets the scroll adjusted bounds /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override Rectangle Bounds { get { GridPanel panel = GridPanel; if (panel != null) { Rectangle r = BoundsRelative; if (panel.IsSubPanel == true) { r.X -= HScrollOffset; if (IsVFrozen == false) r.Y -= VScrollOffset; } return (r); } return (Rectangle.Empty); } } #endregion #region DescendingSortImage /// /// Gets or sets the Descending sort image /// [DefaultValue(null), Category("Appearance")] [Description("Indicates the Descending sort image.")] public Image DescendingSortImage { get { return (_DescendingSortImage); } set { if (_DescendingSortImage != value) { _DescendingSortImage = value; OnPropertyChangedEx("DescendingSortImage", VisualChangeType.Render); } } } #region GetDescendingSortImage internal Image GetDescendingSortImage(GridColumn column) { if (_DescendingSortImage != null) return (_DescendingSortImage); if (_DescendingSortImageIndex >= 0) { ImageList imageList = GridPanel.ImageList; if (imageList != null && _DescendingSortImageIndex < imageList.Images.Count) return (imageList.Images[_DescendingSortImageIndex]); } return (GetDescendingSortImageEx(column)); } #region GetDescendingSortImageEx internal Image GetDescendingSortImageEx(GridColumn column) { StyleState state = GetStyleState(column, column.IsSelected); Image cacheImage = _DescendingSortCacheImages[(int)state]; if (cacheImage == null) { int width = Dpi.Width5; int height = Dpi.Height3; if ((width % 2) == 0) width++; Rectangle r = new Rectangle(0, 0, width, height); Image image = new Bitmap(width, height); using (Graphics g = Graphics.FromImage(image)) { g.SmoothingMode = SmoothingMode.AntiAlias; using (GraphicsPath path = new GraphicsPath()) { Point pt = new Point(r.X + width / 2, r.Bottom - 1); Point[] pts = { pt, new Point(r.Right - 1, r.Top), new Point(r.Left, r.Top), pt }; path.AddLines(pts); ColumnHeaderRowVisualStyle style = GetEffectiveRowHeaderStyleEx(state); Color color = style.SortIndicatorColor; if (color.IsEmpty) color = Color.Black; using (Brush br = new SolidBrush(color)) g.FillPath(br, path); using (Pen pen = new Pen(color)) g.DrawPath(pen, path); } } _DescendingSortCacheImages[(int)state] = image; cacheImage = image; } return (cacheImage); } #endregion #endregion #endregion #region DescendingSortImageIndex /// /// Gets or sets the Descending Sort Image index /// [Browsable(true), DefaultValue(-1)] [Category("Appearance"), Description("Indicates the Descending Sort Image index.")] [Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] [TypeConverter(typeof(ImageIndexConverter))] public int DescendingSortImageIndex { get { return (_DescendingSortImageIndex); } set { if (_DescendingSortImageIndex != value) { _DescendingSortImageIndex = value; OnPropertyChangedEx("DescendingSortImageIndex", VisualChangeType.Layout); } } } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] private void ResetDescendingSortImageIndex() { _DescendingSortImageIndex = -1; } #endregion #region FilterImage /// /// Gets or sets the default /// image to display in the column header. /// [DefaultValue(null), Category("Filtering")] [Description("Indicates the default image to display in the column header.")] public Image FilterImage { get { return (_FilterImage); } set { if (_FilterImage != value) { _FilterImage = value; NeedsMeasured = true; OnPropertyChangedEx("FilterImage", VisualChangeType.Layout); } } } #region GetFilterImage internal Image GetFilterImage(GridColumn column) { bool inFilter; StyleState state = GetFilterImageState(column, out inFilter); return (GetFilterImage(column, state, inFilter)); } internal Image GetFilterImage( GridColumn column, StyleState state, bool inFilter) { if (_FilterImage != null) return (_FilterImage); if (_FilterImageIndex >= 0) { ImageList imageList = GridPanel.ImageList; if (imageList != null && _FilterImageIndex < imageList.Images.Count) return (imageList.Images[_FilterImageIndex]); } return (GetFilterImageEx(state, inFilter)); } #region GetFilterImageEx private Image GetFilterImageEx(StyleState state, bool inFilter) { int n = (int)state; if (inFilter == true) n += ImageCacheSize; Image cacheImage = _FilterCacheImages[n]; if (cacheImage == null) { Image image = new Bitmap(Dpi.Width8, Dpi.Height8); using (Graphics g = Graphics.FromImage(image)) { g.SmoothingMode = SmoothingMode.AntiAlias; using (GraphicsPath path = new GraphicsPath()) { Point[] pts = { new Point(0, 0), new Point(Dpi.Width7, 0), new Point(Dpi.Width7, Dpi.Height1), new Point(Dpi.Width4, Dpi.Height4), new Point(Dpi.Width4, Dpi.Height7), new Point(Dpi.Width3, Dpi.Height6), new Point(Dpi.Width3, Dpi.Height4), new Point(0, Dpi.Height1), new Point(0, 0), }; path.AddLines(pts); Rectangle r = new Rectangle(Dpi.Width1, Dpi.Height1, Dpi.Width6, Dpi.Height3); ColumnHeaderRowVisualStyle style = GetEffectiveRowHeaderStyleEx(state); Color color = style.FilterBorderColor; if (color.IsEmpty) color = Color.DimGray; if (inFilter == false) style = GetEffectiveRowHeaderStyleEx(state & ~StyleState.MouseOver); Background back = (style.FilterBackground != null && style.FilterBackground.IsEmpty == false) ? style.FilterBackground : new Background(Color.White); using (Brush br = back.GetBrush(r)) g.FillPath(br, path); using (Pen pen = new Pen(color)) g.DrawPath(pen, path); } } _FilterCacheImages[n] = image; cacheImage = image; } return (cacheImage); } #region GetFilterImageState private StyleState GetFilterImageState(GridColumn column, out bool inFilter) { inFilter = false; StyleState state = GetRowHeaderState(); state &= ~(StyleState.MouseOver | StyleState.Selected); GridColumn hitColumn = _HitItem as GridColumn; if (column == hitColumn) { state |= StyleState.MouseOver; if (_HitArea == HeaderArea.InFilterMenu) inFilter = true; } if (column != null && string.IsNullOrEmpty(column.FilterExpr) == false) state |= StyleState.Selected; return (state); } #endregion #endregion #endregion #endregion #region FilterImageAlignment /// /// Gets or sets the alignment of the filter Image /// [DefaultValue(Alignment.NotSet), Category("Appearance")] [Description("Indicates the alignment of the filter Image.")] public Alignment FilterImageAlignment { get { return (_FilterImageAlignment); } set { if (_FilterImageAlignment != value) { _FilterImageAlignment = value; OnPropertyChangedEx("FilterImageAlignment", VisualChangeType.Layout); } } } #endregion #region FilterImageIndex /// /// Gets or sets the Filter image index /// [Browsable(true), DefaultValue(-1)] [Category("Appearance"), Description("Indicates the Filter Row image index.")] [Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] [TypeConverter(typeof(ImageIndexConverter))] public int FilterImageIndex { get { return (_FilterImageIndex); } set { if (_FilterImageIndex != value) { _FilterImageIndex = value; OnPropertyChangedEx("FilterImageIndex", VisualChangeType.Layout); } } } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] private void ResetFilterImageIndex() { _FilterImageIndex = -1; } #endregion #region FilterImageVisibility /// /// Gets or sets the visibility of the header filter image /// [DefaultValue(ImageVisibility.Auto), Category("Filtering")] [Description("Indicates the visibility of the header filter image.")] public ImageVisibility FilterImageVisibility { get { return (_FilterImageVisibility); } set { if (_FilterImageVisibility != value) { _FilterImageVisibility = value; OnPropertyChangedEx("FilterImageVisibility", VisualChangeType.Layout); } } } #endregion #region GroupHeaders /// /// Gets a reference to the collection of grid columns /// [Category("Appearance")] [Description("Indicates the collection of grid columns.")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public ColumnGroupHeaderCollection GroupHeaders { get { if (_GroupHeaders == null) { _GroupHeaders = new ColumnGroupHeaderCollection(); _GroupHeaders.Parent = this; _GroupHeaders.CollectionChanged += GroupHeadersCollectionChanged; _GroupHeaders.PropertyChanged += GroupHeadersPropertyChanged; _GroupHeaders.GroupHeaderMarkupLinkClick += GroupHeaderMarkupLinkClick; } return (_GroupHeaders); } } #region GroupHeadersCollectionChanged void GroupHeadersCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { NeedsMeasured = true; SuperGrid.StyleUpdateCount++; InvalidateLayout(); } #endregion #region GroupHeadersPropertyChanged void GroupHeadersPropertyChanged(object sender, PropertyChangedEventArgs e) { NeedsMeasured = true; InvalidateStyle(); InvalidateLayout(); } #endregion #region GroupHeadersMarkupLinkClick void GroupHeaderMarkupLinkClick(object sender, GroupHeaderMarkupLinkClickEventArgs e) { SuperGrid.DoColumnGroupHeaderMarkupLinkClickEvent( GridPanel, this, e.GroupHeader, e.HyperLink); } #endregion #endregion #region MinRowHeight /// /// Gets or sets the minimum height of the ColumnHeader row /// [DefaultValue(0), Category("Style")] [Description("Indicates the minimum height of the ColumnHeader row")] public int MinRowHeight { get { return (_MinRowHeight); } set { if (_MinRowHeight != value) { if (value < 0) throw new Exception("MinRowHeight cannot be negative"); _MinRowHeight = value; NeedsMeasured = true; OnPropertyChangedEx("MinRowHeight", VisualChangeType.Layout); } } } #endregion #region RowHeaderText /// /// Gets or sets the associated row header text (only /// displayed if TopLeftHeaderSelectBehavior is set to NoSelection). /// [DefaultValue(null), Category("Appearance")] [Description("Indicates the associated row header text (only displayed if TopLeftHeaderSelectBehavior is set to NoSelection).")] public string RowHeaderText { get { return (_RowHeaderText); } set { if (_RowHeaderText != value) { _RowHeaderText = value; NeedsMeasured = true; OnPropertyChangedEx("RowHeaderText", VisualChangeType.Render); } } } #endregion #region RowHeight /// /// Gets or sets the height of the ColumnHeader row /// [DefaultValue(0), Category("Style")] [Description("Indicates the height of the ColumnHeader row")] public int RowHeight { get { return (_RowHeight); } set { if (_RowHeight != value) { if (value < 0) throw new Exception("RowHeight cannot be negative"); _RowHeight = value; NeedsMeasured = true; OnPropertyChangedEx("RowHeight", VisualChangeType.Layout); } } } #endregion #region ShowFilterToolTips /// /// Gets or sets whether tooltips are shown when over the filter image /// [DefaultValue(true), Category("Filtering")] [Description("Indicates whether tooltips are shown when over the filter image.")] public bool ShowFilterToolTips { get { return (_ShowFilterToolTips); } set { if (value != _ShowFilterToolTips) { _ShowFilterToolTips = value; OnPropertyChanged("ShowFilterToolTips"); } } } #endregion #region ShowHeaderImages /// /// Gets or sets whether Column Header images are displayed /// [DefaultValue(true), Category("Appearance")] [Description("Indicates whether Column Header images are displayed.")] public bool ShowHeaderImages { get { return (_ShowHeaderImages); } set { if (_ShowHeaderImages != value) { _ShowHeaderImages = value; NeedsMeasured = true; OnPropertyChangedEx("ShowHeaderImages", VisualChangeType.Layout); } } } #endregion #region ShowGroupColumnHeaders /// /// Gets or sets whether column headers are shown /// by default when the columns are within a grouped header /// [DefaultValue(true), Category("Appearance")] [Description("Indicates whether column headers are shown by default when the columns are within a grouped header.")] public bool ShowGroupColumnHeaders { get { return (_ShowGroupColumnHeaders); } set { if (_ShowGroupColumnHeaders != value) { _ShowGroupColumnHeaders = value; OnPropertyChangedEx("ShowGroupColumnHeaders", VisualChangeType.Layout); } } } #endregion #region ShowToolTips /// /// Gets or sets whether tooltips are shown for the column header /// [DefaultValue(true), Category("Filtering")] [Description("Indicates whether tooltips are shown for the column header.")] public bool ShowToolTips { get { return (_ShowToolTips); } set { if (value != _ShowToolTips) { _ShowToolTips = value; OnPropertyChanged("ShowToolTips"); } } } #endregion #region SortImageAlignment /// /// Gets or sets the alignment of the Sort Images /// [DefaultValue(Alignment.NotSet), Category("Appearance")] [Description("Indicates the alignment of the Sort Images.")] public Alignment SortImageAlignment { get { return (_SortImageAlignment); } set { if (_SortImageAlignment != value) { _SortImageAlignment = value; OnPropertyChangedEx("SortImageAlignment", VisualChangeType.Layout); } } } #endregion #endregion #region MeasureOverride /// /// Performs the layout of the item and sets /// the Size property to size that item will take. /// /// Layout information. /// /// protected override void MeasureOverride( GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize) { GridPanel panel = stateInfo.GridPanel; ResetProcessStates(panel); Size sizeNeeded = MeasureGroupHeaders(layoutInfo, constraintSize, panel); MeasureColumnHeaders(layoutInfo, constraintSize, panel, ref sizeNeeded); if (panel.ShowRowHeaders == true) sizeNeeded.Width += panel.RowHeaderWidthEx; Size = sizeNeeded; } #region MeasureGroupHeaders private Size MeasureGroupHeaders( GridLayoutInfo layoutInfo, Size constraintSize, GridPanel panel) { Size sizeNeeded = Size.Empty; if (_GroupHeaders != null) { foreach (ColumnGroupHeader cgh in _GroupHeaders) { if (cgh.Visible == true) { Size size = MeasureGroupHeader(layoutInfo, constraintSize, panel, cgh); sizeNeeded.Width += size.Width; sizeNeeded.Height = Math.Max(size.Height, sizeNeeded.Height); } } } return (sizeNeeded); } #region MeasureGroupHeader private Size MeasureGroupHeader(GridLayoutInfo layoutInfo, Size constraintSize, GridPanel panel, ColumnGroupHeader cgh) { Size sizeNeeded = MeasureGroupHeaderColumn(layoutInfo, constraintSize, panel, cgh); if (cgh.RowHeight > 0) { sizeNeeded.Height = Dpi.Height(cgh.RowHeight); } else { int mrh = Dpi.Height(cgh.MinRowHeight); if (sizeNeeded.Height < mrh) sizeNeeded.Height = mrh; } cgh.ContentSize = sizeNeeded; if (cgh.GroupHeaders.Count > 0) { Size subSize = Size.Empty; foreach (ColumnGroupHeader gh in cgh.GroupHeaders) { Size size = MeasureGroupHeader(layoutInfo, constraintSize, panel, gh); subSize.Height = Math.Max(subSize.Height, size.Height); subSize.Width += size.Width; } sizeNeeded.Height += subSize.Height; sizeNeeded.Width = Math.Max(sizeNeeded.Width, subSize.Width); } else { Size baseSize = Size.Empty; GridColumnCollection columns = _Columns; bool showColumnHeaders = GetShowRootColumnHeaders(cgh); int[] map = columns.DisplayIndexMap; for (int i = cgh.StartDisplayIndex; i <= cgh.EndDisplayIndex; i++) { if ((uint)i >= map.Length) break; int index = map[i]; GridColumn column = columns[index]; if (column.Visible == true) { if (showColumnHeaders == true) { Size size = MeasureHeader(layoutInfo, constraintSize, panel, column); baseSize.Width += size.Width; baseSize.Height = Math.Max(baseSize.Height, size.Height); } } } sizeNeeded.Height += baseSize.Height; if (constraintSize.Width > 0) sizeNeeded.Width = baseSize.Width; else sizeNeeded.Width = Math.Max(sizeNeeded.Width, baseSize.Width); } cgh.Size = sizeNeeded; return (sizeNeeded); } #region MeasureGroupHeaderColumn private Size MeasureGroupHeaderColumn(GridLayoutInfo layoutInfo, Size constraintSize, GridPanel panel, ColumnGroupHeader cgh) { ColumnHeaderVisualStyle style = GetSizingStyle(panel, cgh); Size sizeNeeded = MeasureGroupHeaderTextAndImage(layoutInfo, constraintSize, panel, cgh, style); sizeNeeded.Width += Dpi.Width8; sizeNeeded.Height += Dpi.Height4; return (sizeNeeded); } #region MeasureGroupHeaderTextAndImage private Size MeasureGroupHeaderTextAndImage(GridLayoutInfo layoutInfo, Size constraintSize, GridPanel panel, ColumnGroupHeader cgh, ColumnHeaderVisualStyle style) { Size sizeNeeded = Size.Empty; object figure = (_ShowHeaderImages == true) ? style.GetFigure(panel) : null; Size figureSize = style.GetFigureSize(panel); Alignment imageAlignment = style.ImageAlignment; if (style.IsOverlayImage == true) imageAlignment = Alignment.MiddleCenter; Size borderSize = style.GetBorderSize(true); int bwidth = (borderSize.Width * 2); int bheight = (borderSize.Height * 2); int width = constraintSize.Width > 0 ? GetDefaultGroupHeaderWidth(panel, cgh) : 0; if (width > 0) { width -= bwidth; switch (imageAlignment) { case Alignment.TopCenter: case Alignment.MiddleCenter: case Alignment.BottomCenter: break; default: width -= figureSize.Width; break; } } Size contentSize = MeasureGroupHeaderText(layoutInfo.Graphics, cgh, style, new Size(width, 0)); switch (imageAlignment) { case Alignment.MiddleCenter: sizeNeeded.Height = Math.Max(figureSize.Height, contentSize.Height) + bheight; sizeNeeded.Width = Math.Max(figureSize.Width, contentSize.Width) + bwidth; break; case Alignment.TopCenter: case Alignment.BottomCenter: sizeNeeded.Width = Math.Max(figureSize.Width, contentSize.Width) + bwidth; sizeNeeded.Height = contentSize.Height + figureSize.Height + bheight; break; default: sizeNeeded.Width = contentSize.Width + figureSize.Width + bwidth; sizeNeeded.Height = Math.Max(figureSize.Height, contentSize.Height) + bheight; break; } return (sizeNeeded); } #region GetDefaultGroupHeaderWidth private int GetDefaultGroupHeaderWidth( GridPanel panel, ColumnGroupHeader cgh) { int width = 0; GridColumnCollection columns = panel.Columns; int[] map = columns.DisplayIndexMap; for (int i = cgh.StartDisplayIndex; i <= cgh.EndDisplayIndex; i++) { if ((uint)i >= map.Length) break; int index = map[i]; GridColumn column = columns[index]; if (column.Visible == true) width += column.Size.Width; } return (width); } #endregion #region MeasureGroupHeaderText private Size MeasureGroupHeaderText(Graphics g, ColumnGroupHeader cgh, CellVisualStyle style, Size constraintSize) { Size size = Size.Empty; string s = GetHeaderText(cgh); if (string.IsNullOrEmpty(s) == false) { if (cgh.HeaderTextMarkup != null) { size = GetMarkupTextSize(g, cgh.HeaderTextMarkup, style, constraintSize.Width); cgh.HeaderTextSize = size; } else { eTextFormat tf = style.GetTextFormatFlags(); size = (constraintSize.IsEmpty == true) ? TextHelper.MeasureText(g, s, style.Font) : TextHelper.MeasureText(g, s, style.Font, constraintSize, tf); } } return (size); } #endregion #endregion #endregion #endregion #endregion #region MeasureColumnHeaders private void MeasureColumnHeaders( GridLayoutInfo layoutInfo, Size constraintSize, GridPanel panel, ref Size sizeNeeded) { GridColumnCollection columns = _Columns; for (int i = 0; i < columns.Count; i++) { GridColumn column = columns[i]; if (column.Processed == false) { Size size = MeasureHeader(layoutInfo, constraintSize, panel, column); sizeNeeded.Width += size.Width; sizeNeeded.Height = Math.Max(size.Height, sizeNeeded.Height); } } } #endregion #region MeasureHeader internal Size MeasureHeader(GridLayoutInfo layoutInfo, Size constraintSize, GridPanel panel, GridColumn column) { Size sizeNeeded = Size.Empty; ColumnHeaderVisualStyle style = GetSizingStyle(panel, column); MeasureTextAndImage(layoutInfo, constraintSize, panel, column, style, ref sizeNeeded); MeasureSortAndFilter(panel, column, style, ref sizeNeeded); sizeNeeded.Width += Dpi.Width8; sizeNeeded.Height += Dpi.Height4; if (Dpi.Height(_RowHeight) > 0) sizeNeeded.Height = Dpi.Height(_RowHeight); else if (sizeNeeded.Height < Dpi.Height(_MinRowHeight)) sizeNeeded.Height = Dpi.Height(_MinRowHeight); column.HeaderSize = sizeNeeded; column.Processed = true; return (sizeNeeded); } #region MeasureTextAndImage private void MeasureTextAndImage(GridLayoutInfo layoutInfo, Size constraintSize, GridPanel panel, GridColumn column, ColumnHeaderVisualStyle style, ref Size sizeNeeded) { Size figureSize = (_ShowHeaderImages == true) ? style.GetFigureSize(panel) : Size.Empty; Alignment imageAlignment = style.ImageAlignment; if (style.IsOverlayImage == true) imageAlignment = Alignment.MiddleCenter; Size borderSize = style.GetBorderSize(true); int bwidth = (borderSize.Width * 2); int bheight = (borderSize.Height * 2); int width = constraintSize.Width > 0 ? column.Size.Width : 0; if (width > 0) { width -= bwidth; switch (imageAlignment) { case Alignment.TopCenter: case Alignment.MiddleCenter: case Alignment.BottomCenter: break; default: width -= figureSize.Width; break; } } Size contentSize = MeasureHeaderText(layoutInfo.Graphics, column, style, new Size(width, 0)); if (width == 0) column.HeaderTextSize = contentSize; switch (imageAlignment) { case Alignment.MiddleCenter: sizeNeeded.Height = Math.Max(figureSize.Height, contentSize.Height) + bheight; sizeNeeded.Width = Math.Max(figureSize.Width, contentSize.Width) + bwidth; break; case Alignment.TopCenter: case Alignment.BottomCenter: sizeNeeded.Width = Math.Max(figureSize.Width, contentSize.Width) + bwidth; sizeNeeded.Height = contentSize.Height + figureSize.Height + bheight; break; default: sizeNeeded.Width = contentSize.Width + figureSize.Width + bwidth; sizeNeeded.Height = Math.Max(figureSize.Height, contentSize.Height) + bheight; break; } } #region MeasureHeaderText private Size MeasureHeaderText(Graphics g, GridColumn column, CellVisualStyle style, Size constraintSize) { Size size = Size.Empty; string s = column.GetHeaderText(); if (string.IsNullOrEmpty(s) == false) { if (column.HeaderTextMarkup != null) { size = GetMarkupTextSize(g, column.HeaderTextMarkup, style, constraintSize.Width > 0 ? constraintSize.Width : 10000); column.HeaderTextSize = size; } else { eTextFormat tf = style.GetTextFormatFlags(); size = (constraintSize.IsEmpty == true) ? TextHelper.MeasureText(g, s, style.Font) : TextHelper.MeasureText(g, s, style.Font, constraintSize, tf); } } return (size); } #region GetMarkupTextSize private Size GetMarkupTextSize(Graphics g, BodyElement textMarkup, CellVisualStyle style, int width) { MarkupDrawContext d = new MarkupDrawContext(g, style.Font, style.TextColor, false); textMarkup.InvalidateElementsSize(); textMarkup.Measure(new Size(width, 0), d); return (textMarkup.Bounds.Size); } #endregion #endregion #endregion #region MeasureSortAndFilter private void MeasureSortAndFilter(GridPanel panel, GridColumn column, ColumnHeaderVisualStyle style, ref Size sizeNeeded) { Alignment sortAlignment = (_SortImageAlignment == Alignment.NotSet) ? Alignment.TopCenter : _SortImageAlignment; Alignment filterAlignment = (_FilterImageAlignment == Alignment.NotSet) ? Alignment.MiddleLeft : _FilterImageAlignment; int imsHeight = 0; if (panel.SortLevel != SortLevel.None) { imsHeight = GetPartSizeNeeded( GetAscendingSortImage(column), style, sortAlignment, ref sizeNeeded); } int imfHeight = 0; if (FilterCanBeVisible(panel) == true) { imfHeight = GetPartSizeNeeded( GetFilterImage(column), style, filterAlignment, ref sizeNeeded); } if (imsHeight > 0 && imfHeight > 0) { if (VAlignment(sortAlignment) == VAlignment(filterAlignment)) { int n = Math.Max(imsHeight, imfHeight); sizeNeeded.Height += n; if (VAlignment(style.Alignment) == 1) sizeNeeded.Height += n; } else sizeNeeded.Height += (imsHeight + imfHeight); } else { int n = imsHeight + imfHeight; sizeNeeded.Height += n; if (VAlignment(style.Alignment) == 1) sizeNeeded.Height += n; } } #region GetPartSizeNeeded private int GetPartSizeNeeded(Image image, ColumnHeaderVisualStyle style, Alignment alignment, ref Size sizeNeeded) { int height = 0; if (image != null) { if (alignment != Alignment.TopCenter && alignment != Alignment.MiddleCenter && alignment != Alignment.BottomCenter) { sizeNeeded.Width += (image.Width + 4); } if (alignment == Alignment.MiddleLeft || alignment == Alignment.MiddleCenter || alignment == Alignment.MiddleRight || VAlignment(alignment) == VAlignment(style.Alignment)) { sizeNeeded.Height = Math.Max(sizeNeeded.Height, image.Height); } else { height = (image.Height + 2); } } return (height); } #endregion #region FilterCanBeVisible private bool FilterCanBeVisible(GridPanel panel) { if (panel.EnableFiltering == true && panel.EnableColumnFiltering == true) { if (FilterImageVisibility != ImageVisibility.Never) return (true); } return (false); } #endregion #endregion #endregion #endregion #region ArrangeOverride /// /// Performs the arrange pass layout of the item /// when final position and size of the item has been set. /// /// Layout information. /// /// Layout bounds protected override void ArrangeOverride(GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Rectangle layoutBounds) { GridPanel panel = Parent as GridPanel; if (panel != null) { ArrangeGroupHeader(panel, GroupHeaders, 0); foreach (GridColumn col in panel.Columns) { if (col.Visible == true) UpdateImageBounds(panel, col); } } } #region ArrangeGroupHeader private void ArrangeGroupHeader( GridPanel panel, IEnumerable csc, int dy) { if (csc != null) { foreach (ColumnGroupHeader cgh in csc) { if (cgh.Visible == true) { Size oldSize = cgh.BoundsRelative.Size; cgh.BoundsRelative = GetGroupHeaderBounds(panel, cgh, dy); cgh.Size = new Size(cgh.Size.Width, Bounds.Height - dy); ArrangeGroupHeader(panel, cgh.GroupHeaders, dy + cgh.BoundsRelative.Height); if (oldSize != cgh.BoundsRelative.Size) SuperGrid.DoColumnGroupHeaderResizedEvent(panel, cgh, oldSize); } } } } #region GetGroupHeaderBounds private Rectangle GetGroupHeaderBounds( GridPanel panel, ColumnGroupHeader cgh, int dy) { GridColumnCollection columns = panel.Columns; Rectangle r = Rectangle.Empty; int[] map = columns.DisplayIndexMap; bool showColHeaders = GetShowRootColumnHeaders(cgh) && cgh.GroupHeaders.Count == 0; for (int i = cgh.StartDisplayIndex; i <= cgh.EndDisplayIndex; i++) { if ((uint)i < columns.Count) { GridColumn column = columns[map[i]]; if (column.Visible == true) { Rectangle q = GetRelativeBounds(panel, column); r = (r.IsEmpty == true) ? q : Rectangle.Union(r, q); r.Height = (showColHeaders == true) ? column.HeaderSize.Height : 0; } } } r.Y += dy; if (cgh.GroupHeaders.Count > 0) { r.Height = cgh.ContentSize.Height; } else { if (showColHeaders == true && cgh.RowHeight > 0) r.Height = Dpi.Height(cgh.RowHeight); else r.Height = (Bounds.Bottom - r.Bottom); } return (r); } #endregion #endregion #endregion #region RenderOverride /// /// Performs drawing of the item and its children. /// /// Holds contextual rendering information. protected override void RenderOverride(GridRenderInfo renderInfo) { GridPanel panel = Parent as GridPanel; if (panel != null) { ResetProcessStates(panel); Graphics g = renderInfo.Graphics; Rectangle bounds = Bounds; ColumnHeaderRowVisualStyle style = GetEffectiveRowHeaderStyle(); GridPanelVisualStyle pstyle = panel.GetEffectiveStyle(); if (SuperGrid.DoPreRenderColumnHeaderEvent(g, this, null, RenderParts.Background, bounds) == false) { RenderRowBackground(g, style, bounds); SuperGrid.DoPostRenderColumnHeaderEvent(g, this, null, RenderParts.Background, bounds); } RenderColumnBorder(g, panel, bounds); if (HScrollOffset == 0 || panel.IsSubPanel || panel.FrozenColumnCount <= 0) { RenderHeaders(panel, renderInfo, false, false); } else { RenderHeaders(panel, renderInfo, true, false); RenderHeaders(panel, renderInfo, true, true); } if (panel.FrozenColumnCount > 0) RenderFrozenColumnMarker(g, panel, pstyle); RenderRowHeader(g, panel, style, pstyle); } } #region RenderRowBackground private void RenderRowBackground( Graphics g, ColumnHeaderRowVisualStyle style, Rectangle bounds) { using (Brush br = style.WhiteSpaceBackground.GetBrush(bounds)) g.FillRectangle(br, bounds); } #endregion #region RenderColumnBorder private void RenderColumnBorder( Graphics g, GridPanel panel, Rectangle bounds) { Rectangle r = bounds; SmoothingMode sm = g.SmoothingMode; g.SmoothingMode = SmoothingMode.None; GridPanelVisualStyle pstyle = panel.GetEffectiveStyle(); if (pstyle.HeaderHLinePattern != LinePattern.None && pstyle.HeaderHLinePattern != LinePattern.NotSet) { using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Height1)) { pen.DashStyle = (DashStyle)pstyle.HeaderHLinePattern; g.DrawLine(pen, r.X, r.Bottom - 1, r.Right - 1, r.Bottom - 1); g.DrawLine(pen, r.X, r.Top - 1, r.Right - 1, r.Top - 1); } } if (pstyle.HeaderVLinePattern != LinePattern.None && pstyle.HeaderVLinePattern != LinePattern.NotSet) { using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Width1)) { pen.DashStyle = (DashStyle)pstyle.HeaderVLinePattern; g.DrawLine(pen, r.Right - 1, r.Top - 1, r.Right - 1, r.Bottom - 1); } } g.SmoothingMode = sm; } #endregion #region RenderHeaders private void RenderHeaders(GridPanel panel, GridRenderInfo renderInfo, bool chkFrozen, bool frozen) { Graphics g = renderInfo.Graphics; Rectangle clip = renderInfo.ClipRectangle; RenderGroupHeaders(g, panel, clip, GroupHeaders, chkFrozen, frozen); RenderColumnHeaders(g, panel, clip, chkFrozen, frozen); } #region RenderGroupHeaders private void RenderGroupHeaders(Graphics g, GridPanel panel, Rectangle clip, IEnumerable csc, bool chkFrozen, bool frozen) { if (csc != null) { foreach (ColumnGroupHeader cgh in csc) { if (cgh.Visible == true) { if (chkFrozen == false || (IsGroupHeaderHFrozen(panel, cgh) == frozen)) { Rectangle r = GetSubContScrollBounds(panel, cgh); if (clip.IsEmpty == true || r.IntersectsWith(clip) == true) { Rectangle bounds = GetSubScrollBounds(panel, cgh); RenderGroupHeader(g, panel, cgh, bounds); if (cgh.GroupHeaders.Count > 0) RenderGroupHeaders(g, panel, Rectangle.Empty, cgh.GroupHeaders, chkFrozen, frozen); RenderBaseHeaders(g, panel, cgh); } else { if (cgh.GroupHeaders.Count > 0) RenderGroupHeaders(g, panel, Rectangle.Empty, cgh.GroupHeaders, chkFrozen, frozen); } } } } } } #region RenderGroupHeader private void RenderGroupHeader( Graphics g, GridPanel panel, ColumnGroupHeader cgh, Rectangle bounds) { if (bounds.IsEmpty == false) { ColumnHeaderVisualStyle style = GetEffectiveStyle(cgh); if (bounds.Width > 0 && bounds.Height > 0) { if (SuperGrid.DoPreRenderColumnGroupHeaderEvent(g, this, cgh, RenderParts.Background, bounds) == false) { RenderBackground(g, style, bounds); SuperGrid.DoPostRenderColumnGroupHeaderEvent(g, this, cgh, RenderParts.Background, bounds); } RenderColumnBorder(g, panel, bounds); Rectangle r = bounds; Rectangle t = GetContentBounds(panel, style, r); t = GetAdjustedBounds(style, t); if (style.ImageOverlay == ImageOverlay.None || style.ImageOverlay == ImageOverlay.Bottom) { RenderHeaderImage(g, panel, style, bounds, t); } if (SuperGrid.DoPreRenderColumnGroupHeaderEvent(g, this, cgh, RenderParts.Content, t) == false) { RenderGroupHeaderText(g, style, cgh, t); SuperGrid.DoPostRenderColumnGroupHeaderEvent(g, this, cgh, RenderParts.Content, t); } if (style.ImageOverlay == ImageOverlay.Top) RenderHeaderImage(g, panel, style, bounds, t); r = GetBorderRect(style, r); if (SuperGrid.DoPreRenderColumnGroupHeaderEvent(g, this, cgh, RenderParts.Border, r) == false) { if (r.Width > 0 && r.Height > 0) style.RenderBorder(g, r); SuperGrid.DoPostRenderColumnGroupHeaderEvent(g, this, cgh, RenderParts.Border, r); } } } } #region RenderGroupHeaderText private void RenderGroupHeaderText(Graphics g, ColumnHeaderVisualStyle style, ColumnGroupHeader cgh, Rectangle r) { if (_MouseDownButtons == MouseButtons.Left) r = AdjustTextHeaderBounds(cgh, r, GridPanel.ColumnGroupHeaderClickBehavior); if (cgh.HeaderTextMarkup != null) { RenderTextMarkup(g, cgh.HeaderTextMarkup, style, r); } else { string s = GetHeaderText(cgh); if (string.IsNullOrEmpty(s) == false) { TextDrawing.DrawString(g, s, style.Font, style.TextColor, r, style.GetTextFormatFlags()); } } } #region GetHeaderText private string GetHeaderText(ColumnGroupHeader cgh) { return (cgh.HeaderText ?? cgh.Name); } #endregion #endregion #endregion #region RenderBaseHeaders private void RenderBaseHeaders(Graphics g, GridPanel panel, ColumnGroupHeader cgh) { int[] map = panel.Columns.DisplayIndexMap; for (int i = cgh.StartDisplayIndex; i <= cgh.EndDisplayIndex; i++) { if ((uint)i >= map.Length) break; RenderBaseHeader(g, panel, cgh, map[i]); } } #region RenderBaseHeader private void RenderBaseHeader(Graphics g, GridPanel panel, ColumnGroupHeader cgh, int i) { GridColumn col = panel.Columns[i]; if (col.Visible == true && col.Processed == false) { Rectangle r = GetBounds(panel, col); int n = cgh.Size.Height - cgh.BoundsRelative.Height; r.Y = r.Bottom - n; r.Height = n; if (GetShowRootColumnHeaders(cgh) == true || cgh.GroupHeaders.Count > 0) { RenderColumnHeader(g, panel, col, r, true); } else { RenderColumnBorder(g, panel, r); col.Processed = true; } } } #endregion #endregion #endregion #region RenderColumnHeaders private void RenderColumnHeaders(Graphics g, GridPanel panel, Rectangle clip, bool chkFrozen, bool frozen) { GridColumnCollection columns = _Columns; int[] map = columns.DisplayIndexMap; for (int i = 0; i < map.Length; i++) { int index = map[i]; GridColumn column = columns[index]; if (column.Visible == true && column.Processed == false) { if ((chkFrozen == false) || (frozen == column.IsHFrozen)) { Rectangle r = GetBounds(panel, column); if (r.IntersectsWith(clip) == true) RenderColumnHeader(g, panel, column, r, true); } } } } #region RenderColumnHeader private void RenderColumnHeader(Graphics g, GridPanel panel, GridColumn column, Rectangle bounds, bool fullRender) { ColumnHeaderVisualStyle style = GetEffectiveStyle(column); if (bounds.Width > 0 && bounds.Height > 0) { if (SuperGrid.DoPreRenderColumnHeaderEvent(g, this, column, RenderParts.Background, bounds) == false) { RenderBackground(g, style, bounds); SuperGrid.DoPostRenderColumnHeaderEvent(g, this, column, RenderParts.Background, bounds); } RenderColumnBorder(g, panel, bounds); Rectangle r = bounds; Rectangle t = GetContentBounds(panel, style, r); t = GetAdjustedBounds(style, t); if (style.ImageOverlay == ImageOverlay.None || style.ImageOverlay == ImageOverlay.Bottom) { RenderHeaderImage(g, panel, style, bounds, t); } if (fullRender == true) t = RenderSortAndFilterImage(g, column, style, t); if (SuperGrid.DoPreRenderColumnHeaderEvent(g, this, column, RenderParts.Content, t) == false) { RenderText(g, panel, column, style, t); SuperGrid.DoPostRenderColumnHeaderEvent(g, this, column, RenderParts.Content, t); } if (style.ImageOverlay == ImageOverlay.Top) RenderHeaderImage(g, panel, style, bounds, t); r = GetBorderRect(style, r); if (SuperGrid.DoPreRenderColumnHeaderEvent(g, this, column, RenderParts.Border, r) == false) { if (r.Width > 0 && r.Height > 0) style.RenderBorder(g, r); SuperGrid.DoPostRenderColumnHeaderEvent(g, this, column, RenderParts.Border, r); } column.Processed = true; } } #region GetBorderRect private Rectangle GetBorderRect( ColumnHeaderVisualStyle style, Rectangle r) { r.X += style.Margin.Left; r.Width -= style.Margin.Horizontal; r.Y += style.Margin.Top; r.Height -= style.Margin.Vertical; return (r); } #endregion #region RenderBackground private void RenderBackground(Graphics g, VisualStyle style, Rectangle r) { using (Brush br = style.Background.GetBrush(r)) g.FillRectangle(br, r); } #endregion #region RenderSortAndFilterImage private Rectangle RenderSortAndFilterImage( Graphics g, GridColumn column, ColumnHeaderVisualStyle style, Rectangle t) { GridPanel panel = column.Parent as GridPanel; if (panel != null) { Alignment falign = (_FilterImageAlignment == Alignment.NotSet) ? Alignment.MiddleLeft : _FilterImageAlignment; Alignment salign = (_SortImageAlignment == Alignment.NotSet) ? Alignment.TopCenter : _SortImageAlignment; Rectangle rf = GetFilterImageBounds(panel, column); if (rf.IsEmpty == false) { Image filterImage = GetColumnFilterImage(column); if (filterImage != null) g.DrawImageUnscaledAndClipped(filterImage, rf); } Rectangle rs = GetSortImageBounds(panel, column, salign, falign, rf); if (rs.IsEmpty == false) { Image sortImage = GetColumnSortImage(panel, column); if (sortImage != null) g.DrawImageUnscaledAndClipped(sortImage, rs); } if (rf.IsEmpty == false) t = UpdateContentRect(rf, t, falign, style, column); if (rs.IsEmpty == false) t = UpdateContentRect(rs, t, salign, style, column); } t.X += 2; t.Width -= 4; return (t); } #region GetFilterImageBounds private Rectangle GetFilterImageBounds(GridPanel panel, GridColumn column) { if (column != null) { GridColumn hitColumn = _HitItem as GridColumn; if (_FilterImageVisibility == ImageVisibility.Always || (column == hitColumn) || (string.IsNullOrEmpty(column.FilterExpr) == false)) { return (GetScrollBounds(panel, column, column.FilterImageBounds)); } } return (Rectangle.Empty); } #endregion #region GetSortImageBounds private Rectangle GetSortImageBounds(GridPanel panel, GridColumn column, Alignment salign, Alignment falign, Rectangle rf) { Rectangle r = GetScrollBounds(panel, column, column.SortImageBounds); if (r.IsEmpty == false) { if (falign == salign && r.IsEmpty == false) { if (salign == Alignment.TopCenter || salign == Alignment.MiddleCenter || salign == Alignment.BottomCenter) { r.X = rf.X - (r.Width + 1); } } } return (r); } #endregion #region UpdateContentRect private Rectangle UpdateContentRect(Rectangle r, Rectangle t, Alignment alignment, ColumnHeaderVisualStyle style, GridColumn column) { switch (GetStringAlignment(alignment)) { case StringAlignment.Near: int n1 = r.Right - t.Left; switch (GetStringAlignment(style.Alignment)) { case StringAlignment.Center: if (n1 + 3 > (t.Width - column.HeaderTextSize.Width) / 2) { t.X = r.Right; t.Width -= n1; } break; default: t.X = r.Right; t.Width -= n1; break; } break; case StringAlignment.Far: int n2 = t.Right - r.Left; switch (GetStringAlignment(style.Alignment)) { case StringAlignment.Center: if (n2 + 3 > (t.Width - column.HeaderTextSize.Width) / 2) t.Width -= n2; break; default: t.Width -= n2; break; } break; } return (t); } #region GetStringAlignment private StringAlignment GetStringAlignment(Alignment alignment) { switch (alignment) { case Alignment.TopLeft: case Alignment.MiddleLeft: case Alignment.BottomLeft: return (StringAlignment.Near); case Alignment.TopCenter: case Alignment.MiddleCenter: case Alignment.BottomCenter: return (StringAlignment.Center); default: return (StringAlignment.Far); } } #endregion #endregion #endregion #region RenderText private void RenderText(Graphics g, GridPanel panel, GridColumn column, CellVisualStyle style, Rectangle r) { string s = column.GetHeaderText(); if (s != null) { if (_MouseDownButtons == MouseButtons.Left) r = AdjustTextHeaderBounds(column, r, panel.ColumnHeaderClickBehavior); if (column.HeaderTextMarkup != null) { RenderTextMarkup(g, column.HeaderTextMarkup, style, r); } else { TextDrawing.DrawString(g, s, style.Font, style.TextColor, r, style.GetTextFormatFlags()); } } } #region RenderTextMarkup private void RenderTextMarkup(Graphics g, BodyElement textMarkup, CellVisualStyle style, Rectangle r) { MarkupDrawContext d = new MarkupDrawContext(g, style.Font, style.TextColor, false); textMarkup.Arrange(new Rectangle(r.Location, r.Size), d); Size size = textMarkup.Bounds.Size; switch (style.Alignment) { case Alignment.MiddleLeft: case Alignment.MiddleCenter: case Alignment.MiddleRight: if (r.Height > size.Height) r.Y += (r.Height - size.Height) / 2; break; default: if (r.Height > size.Height) r.Y = r.Bottom - size.Height; break; } textMarkup.Bounds = new Rectangle(r.Location, size); Region oldClip = g.Clip; try { g.SetClip(r, CombineMode.Intersect); textMarkup.Render(d); } finally { g.Clip = oldClip; } } #endregion #endregion #region VAlignment private int VAlignment(Alignment alignment) { switch (alignment) { case Alignment.TopLeft: case Alignment.TopCenter: case Alignment.TopRight: return (0); case Alignment.MiddleLeft: case Alignment.MiddleCenter: case Alignment.MiddleRight: return (1); default: return (2); } } #endregion #region GetColumnSortImage internal Image GetColumnSortImage(GridPanel panel, GridColumn column) { SortDirection sortDirection = SortDirection.None; if (panel.GroupColumns != null && panel.GroupColumns.Contains(column) == true) { sortDirection = column.GroupDirection; } else if (panel.SortLevel != SortLevel.None) { sortDirection = column.SortDirection; switch (column.SortIndicator) { case SortIndicator.None: sortDirection = SortDirection.None; break; case SortIndicator.Ascending: sortDirection = SortDirection.Ascending; break; case SortIndicator.Descending: sortDirection = SortDirection.Descending; break; } } switch (sortDirection) { case SortDirection.Ascending: return (GetAscendingSortImage(column)); case SortDirection.Descending: return (GetDescendingSortImage(column)); } return (null); } #endregion #region GetFilterImage internal Image GetColumnFilterImage(GridColumn column) { if (column.IsFilteringEnabled == true) { if (_FilterImageVisibility != ImageVisibility.Never) return (GetFilterImage(column)); } return (null); } #endregion #region GetImageBounds private Rectangle GetImageBounds( Image image1, Alignment alignment, ref Rectangle r) { Rectangle u = r; Rectangle t = r; t.Size = image1.Size; switch (alignment) { case Alignment.TopLeft: r.X += t.Width + 2; r.Width -= (t.Width + 2); break; case Alignment.NotSet: case Alignment.TopCenter: t.X += (r.Width - t.Width) / 2; break; case Alignment.TopRight: t.X = r.Right - t.Width; r.Width -= (t.Width + 2); break; case Alignment.MiddleLeft: t.Y += (r.Height - t.Height) / 2; r.X += t.Width + 2; r.Width -= (t.Width + 2); break; case Alignment.MiddleCenter: t.X += (r.Width - t.Width) / 2; t.Y += (r.Height - t.Height) / 2; break; case Alignment.MiddleRight: t.X = r.Right - t.Width; t.Y += (r.Height - t.Height) / 2; r.Width -= (t.Width + 2); break; case Alignment.BottomLeft: r.X += t.Width + 2; r.Width -= (t.Width + 2); t.Y = r.Bottom - t.Height; break; case Alignment.BottomCenter: t.X += (r.Width - t.Width) / 2; t.Y = r.Bottom - t.Height; break; case Alignment.BottomRight: t.X = r.Right - t.Width; t.Y = r.Bottom - t.Height; r.Width -= (t.Width + 2); break; } t.Intersect(u); return (t); } #endregion #endregion #endregion #region AdjustTextHeaderBounds private Rectangle AdjustTextHeaderBounds( object item, Rectangle r, ColumnHeaderClickBehavior cmode) { if (_Reordering == false && item == _MouseDownHitItem) { if (_MouseDownHitArea == HeaderArea.InMarkup || (_MouseDownHitArea == HeaderArea.InContent && cmode == ColumnHeaderClickBehavior.SortAndReorder)) { r.X++; r.Y += 2; r.Height -= 2; } } return (r); } #endregion #region RenderHeaderImage private void RenderHeaderImage(Graphics g, GridPanel panel, ColumnHeaderVisualStyle style, Rectangle bounds, Rectangle r) { if (_ShowHeaderImages == true) { object figure = style.GetFigure(panel); if (figure != null) { Rectangle t = style.GetFigureBounds(panel, r); bounds.Inflate(-1, -1); t.Intersect(bounds); style.RenderFigure(g, panel, t); } } } #endregion #endregion #region RenderFrozenColumnMarker private void RenderFrozenColumnMarker( Graphics g, GridPanel panel, GridPanelVisualStyle pstyle) { GridColumn col = panel.Columns.GetLastVisibleFrozenColumn(); if (col != null) { Rectangle bounds = GetBounds(panel, col); bounds.Y = Bounds.Y; bounds.Height = Bounds.Height; Rectangle r = col.BoundsRelative; r.Y = bounds.Y + Dpi.Width3; r.Height = bounds.Height - Dpi.Width5; if (panel.IsSubPanel == true) r.X -= HScrollOffset; if (r.Height > 0 && r.Width > 0) { using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Width1)) { g.DrawLine(pen, r.Right - Dpi.Width3, r.Top - 1, r.Right - Dpi.Width3, r.Bottom - 1); } } } } #endregion #region RenderRowHeader private void RenderRowHeader(Graphics g, GridPanel panel, ColumnHeaderRowVisualStyle style, GridPanelVisualStyle pstyle) { Rectangle r = GetRowHeaderBounds(panel); if (r.Width > 0 && r.Height > 0) { if (SuperGrid.DoPreRenderColumnHeaderEvent(g, this, null, RenderParts.RowHeader, r) == false) { SmoothingMode sm = g.SmoothingMode; g.SmoothingMode = SmoothingMode.None; using (Brush br = style.RowHeader.Background.GetBrush(r)) g.FillRectangle(br, r); using (Pen pen = new Pen(style.RowHeader.BorderHighlightColor, Dpi.Height1)) g.DrawLine(pen, r.X, r.Top, r.Right - 1, r.Top); using (Pen pen = new Pen(style.RowHeader.BorderHighlightColor, Dpi.Height1)) g.DrawLine(pen, r.X + 1, r.Top, r.X + 1, r.Bottom - 1); using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Height1)) { g.DrawLine(pen, r.X, r.Top - 1, r.Right - 1, r.Top - 1); g.DrawLine(pen, r.X, r.Bottom - 1, r.Right - 1, r.Bottom - 1); } using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Width1)) g.DrawLine(pen, r.Right - 1, r.Top, r.Right - 1, r.Bottom - 1); if (panel.TopLeftHeaderSelectBehavior != TopLeftHeaderSelectBehavior.NoSelection) { RenderRowHeaderIndicator(g, panel, style, r); } else { if (string.IsNullOrEmpty(_RowHeaderText) == false) RenderRowHeaderText(g, _RowHeaderText, style, r); } SuperGrid.DoPostRenderColumnHeaderEvent(g, this, null, RenderParts.RowHeader, r); g.SmoothingMode = sm; } } } #region RenderRowHeaderIndicator private void RenderRowHeaderIndicator(Graphics g, GridPanel panel, ColumnHeaderRowVisualStyle style, Rectangle r) { r.Inflate(-Dpi.Width3, -Dpi.Height3); if (r.Width > 0 && r.Height > 0) { using (GraphicsPath path = new GraphicsPath()) { int n = Math.Min(r.Width, r.Height); if (n > Dpi.Width10) n = Dpi.Width10; Point[] pts = new Point[3]; if (_SelectAllCount != panel.SelectionUpdateCount) { r.X--; r.Y--; pts[0] = new Point(r.Right, r.Bottom - n); pts[1] = new Point(r.Right, r.Bottom); pts[2] = new Point(r.Right - n, r.Bottom); } else { pts[0] = new Point(r.X, r.Y); pts[1] = new Point(r.X + n, r.Y); pts[2] = new Point(r.X, r.Y + n); r.X++; r.Y++; } path.AddPolygon(pts); path.CloseFigure(); if (style.IndicatorBackground.GradientAngle % 45 == 0) n /= 2; r.Width = n - 1; r.Height = n - 1; if (n > 0) { g.SmoothingMode = SmoothingMode.AntiAlias; using (Brush br = style.IndicatorBackground.GetBrush(r)) { if (br is LinearGradientBrush) ((LinearGradientBrush)br).WrapMode = WrapMode.Tile; g.FillPath(br, path); } using (Pen pen = new Pen(style.IndicatorBorderColor)) g.DrawPath(pen, path); } } } } #endregion #region RenderRowHeaderText private void RenderRowHeaderText(Graphics g, string text, ColumnHeaderRowVisualStyle style, Rectangle r) { Font font = style.RowHeader.Font ?? SystemFonts.DefaultFont; Size tSize = TextHelper.MeasureText(g, text, font); r.Inflate(-Dpi.Width2, -Dpi.Height2); eTextFormat tf = ((r.Width <= tSize.Width) ? eTextFormat.Left : eTextFormat.HorizontalCenter) | eTextFormat.NoPadding; tf |= eTextFormat.WordBreak | eTextFormat.VerticalCenter; TextDrawing.DrawString(g, text, font, style.RowHeader.TextColor, r, tf); } #endregion #endregion #endregion #region ResetProcessStates private void ResetProcessStates(GridPanel panel) { for (int i = 0; i < panel.Columns.Count; i++) panel.Columns[i].Processed = false; } #endregion #region Mouse support #region InternalMouseEnter internal override void InternalMouseEnter(EventArgs e) { SuperGrid.ToolTipText = ""; SuperGrid.DoColumnHeaderMouseEnterEvent(this); base.InternalMouseEnter(e); } #endregion #region InternalMouseLeave internal override void InternalMouseLeave(EventArgs e) { if (_LockedColumn == false) { ResetColumnState(); _HitArea = HeaderArea.NoWhere; _HitItem = null; } SuperGrid.ToolTipText = ""; SuperGrid.DoColumnHeaderMouseLeaveEvent(this); base.InternalMouseLeave(e); } #region ResetColumnState internal void ResetColumnState() { GridPanel panel = GridPanel; if (panel != null) { if (_MouseDownHitItem != null) InvalidateItem(panel, _MouseDownHitItem); if (_HitItem != null && (_MouseDownHitItem != _HitItem)) InvalidateItem(panel, _HitItem); if (_HitArea == HeaderArea.InRowHeader) InvalidateRowHeader(); if (_HitArea == HeaderArea.InWhitespace) InvalidateWhitespace(); _MouseDownHitItem = null; } _LockedColumn = false; } internal void ResetColumnStateEx() { ResetColumnState(); _HitItem = null; _HitArea = HeaderArea.NoWhere; } #endregion #endregion #region InternalMouseMove internal override void InternalMouseMove(MouseEventArgs e) { GridPanel panel = Parent as GridPanel; if (panel != null) { if (AllowSelection == true) { if (_Resizing == false) { _LastHitArea = _HitArea; _LastHitItem = _HitItem; _HitArea = GetHitArea(e.Location, ref _HitItem, IsMouseDown); if (_Reordering == false) { if (_HitItem is GridColumn) ProcessColumnMouseMove(e, panel); else if (_HitItem is ColumnGroupHeader) ProcessGroupHeaderMouseMove(e, panel); else ProcessRowHeaderMouseMove(panel); if (_HitArea != _LastHitArea || _LastHitItem != _HitItem) { if (_LastHitItem != null) InvalidateItem(panel, _LastHitItem); if (_HitItem != null) InvalidateItem(panel, _HitItem); if (_HitArea == HeaderArea.InRowHeader || _LastHitArea == HeaderArea.InRowHeader) InvalidateRowHeader(); if (_HitArea == HeaderArea.InWhitespace || _LastHitArea == HeaderArea.InWhitespace) InvalidateWhitespace(); } } } if (IsMouseDown == true) { if (ProcessMouseDownMove(e) == false) { if (_MouseDownHitItem != null) { SuperGrid.EnableAutoScrolling(AutoScrollEnable.Horizontal, ViewRect); StopResize(); StopReorder(); } } } } SuperGrid.DoColumnHeaderMouseMoveEvent(this, e); base.InternalMouseMove(e); } } #region ProcessColumnMouseMove private void ProcessColumnMouseMove(MouseEventArgs e, GridPanel panel) { GridColumn hitColumn = (GridColumn) _HitItem; switch (_HitArea) { case HeaderArea.InContent: SuperGrid.GridCursor = Cursors.Default; if (hitColumn.HeaderTextMarkup != null) { hitColumn.HeaderTextMarkup.MouseMove(SuperGrid, e); if (hitColumn.HeaderTextMarkup.MouseOverElement != null) _HitArea = HeaderArea.InMarkup; } if (_ShowToolTips == true) UpdateToolTip(panel, hitColumn.ToolTip); break; case HeaderArea.InResize: SuperGrid.GridCursor = Cursors.VSplit; SuperGrid.ToolTipText = ""; break; case HeaderArea.InFilterMenu: SuperGrid.GridCursor = Cursors.Hand; if (_ShowFilterToolTips == true && hitColumn.IsFilteringEnabled == true) UpdateToolTip(panel, hitColumn.FilterExpr); break; default: SuperGrid.GridCursor = Cursors.Default; SuperGrid.ToolTipText = ""; break; } } #endregion #region ProcessGroupHeaderMouseMove private void ProcessGroupHeaderMouseMove(MouseEventArgs e, GridPanel panel) { switch (_HitArea) { case HeaderArea.InContent: SuperGrid.GridCursor = Cursors.Default; ColumnGroupHeader cgh = (ColumnGroupHeader)_HitItem; if (cgh.HeaderTextMarkup != null) { cgh.HeaderTextMarkup.MouseMove(SuperGrid, e); if (cgh.HeaderTextMarkup.MouseOverElement != null) _HitArea = HeaderArea.InMarkup; } if (_ShowToolTips == true) UpdateToolTip(panel, cgh.ToolTip); break; case HeaderArea.InResize: SuperGrid.GridCursor = Cursors.VSplit; SuperGrid.ToolTipText = ""; break; default: SuperGrid.GridCursor = Cursors.Default; SuperGrid.ToolTipText = ""; break; } } #endregion #region ProcessRowHeaderMouseMove private void ProcessRowHeaderMouseMove(GridPanel panel) { switch (_HitArea) { case HeaderArea.InRowHeaderResize: SuperGrid.GridCursor = Cursors.VSplit; SuperGrid.ToolTipText = ""; break; case HeaderArea.InRowHeader: SuperGrid.GridCursor = (panel.TopLeftHeaderSelectBehavior != TopLeftHeaderSelectBehavior.NoSelection) ? Cursors.Hand : Cursors.Default; UpdateToolTip(panel, ""); break; default: SuperGrid.GridCursor = Cursors.Default; SuperGrid.ToolTipText = ""; break; } } #endregion #endregion #region UpdateToolTip private void UpdateToolTip(GridPanel panel, string toolTip) { if (_HitArea != _LastHitArea || _LastHitItem != _HitItem) panel.SetHeaderTooltip(this, _HitItem, _HitArea, toolTip); } #endregion #region ProcessMouseDownMove private bool ProcessMouseDownMove(MouseEventArgs e) { GridPanel panel = Parent as GridPanel; if (panel != null) { if (_MouseDownHitArea == HeaderArea.InRowHeaderResize) return (InRowHeaderResize(e.Location, e)); if (_MouseDownHitItem is GridColumn) return (ColumnMouseDownMove(e, panel)); if (_MouseDownHitItem is ColumnGroupHeader) return (GroupHeaderMouseDownMove(e, panel)); } return (false); } #region InRowHeaderResize private bool InRowHeaderResize(Point pt, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { GridPanel panel = Parent as GridPanel; if (panel != null) { if (_Resizing == false) { _Resizing = true; _ResizeWidth = panel.RowHeaderWidthEx; if (panel.ImmediateResize == false) { _SeparatorFw = new FloatWindow(); _SeparatorFw.Opacity = .5; _SeparatorFw.BackColor = Color.Black; _SeparatorFw.Owner = SuperGrid.FindForm(); } } else { if (panel.ImmediateResize == false) ContinueRowHeaderResize(panel, pt); else ResizeRowHeader(panel, pt.X - MouseDownPoint.X); } } return (true); } return (false); } #endregion #region ColumnMouseDownMove private bool ColumnMouseDownMove(MouseEventArgs e, GridPanel panel) { GridColumn hitColumn = (GridColumn)_MouseDownHitItem; Rectangle r = ViewRect; if ((_MouseDownHitArea == HeaderArea.InResize) || (_MouseDownHitArea == HeaderArea.InRowHeaderResize) || (e.X >= r.X && e.X < r.Right) || (hitColumn.IsHFrozen == true && panel.IsSubPanel == false)) { SuperGrid.DisableAutoScrolling(); switch (_MouseDownHitArea) { case HeaderArea.InContent: hitColumn = _MouseDownHitItem as GridColumn; if (hitColumn != null) { if (_HitArea == HeaderArea.InGroupBox && hitColumn.GroupBoxEffectsEx != GroupBoxEffects.None) { if (ColumnInGroupBox(panel, e, hitColumn) == true) return (true); } } if (_HitItem == null) return (false); ColumnInContent(e); break; case HeaderArea.InResize: ColumnInResize(e.Location, e); break; } return (true); } return (false); } #region ColumnInGroupBox private bool ColumnInGroupBox( GridPanel panel, MouseEventArgs e, GridColumn hitColumn) { if (e.Button == MouseButtons.Left) { if (hitColumn != null) { if (panel.VisibleColumnCount > 1) { if (panel.GroupByRow.DragStart(hitColumn) == true) { ResetColumnState(); StopReorder(); _MouseDownHitItem = null; _HitArea = HeaderArea.NoWhere; _HitItem = null; return (true); } } } } return (false); } #endregion #region ColumnInContent private void ColumnInContent(MouseEventArgs e) { if (IsDesignerHosted == false) { if (e.Button == MouseButtons.Left) { GridPanel panel = Parent as GridPanel; if (panel != null) { if (DragStarted(panel, e) == false) { if (panel.ColumnDragBehavior == ColumnDragBehavior.ExtendClickBehavior) { switch (panel.ColumnHeaderClickBehavior) { case ColumnHeaderClickBehavior.SortAndReorder: ProcessMove(e.Location); break; case ColumnHeaderClickBehavior.Select: if (_HitItem != _LastHitItem) ProcessExtendSelection(panel, true); break; } } } } } } } #region DragStarted private bool DragStarted(GridPanel panel, MouseEventArgs e) { if (_HitItem is GridColumn) { if (_DragSelection == true) { if (_DragStarted == false) { if (DragDrop.DragStarted(_MouseDownPoint, e.Location) == true) { _DragStarted = true; if (SuperGrid.DoItemDragEvent((GridColumn)_HitItem, e) == true) { _DragSelection = false; ExtendSelection(panel, true); } } } return (true); } } return (false); } #endregion #region ProcessMove private void ProcessMove(Point pt) { if (_Reordering == false) StartReorder(pt); else ContinueReorder(pt); } #endregion #region ProcessExtendSelection private void ProcessExtendSelection(GridPanel panel, bool extend) { bool ckey = (panel.MultiSelect == true) ? ((Control.ModifierKeys & Keys.Control) == Keys.Control) : false; if (ckey == true) ProcessControlExtend(panel); else ProcessNonControlExtend(panel, extend); _lastSelectedItem = _HitItem; } #region ProcessControlExtend private void ProcessControlExtend(GridPanel panel) { int startIndex = 0; int endIndex = 0; if (GetSelectionIndicees(panel, _lastSelectedItem, _HitItem, ref startIndex, ref endIndex, false) == true) { int mdStart = 0; int mdEnd = 0; GetSelectionIndicees(panel, _MouseDownHitItem, _MouseDownHitItem, ref mdStart, ref mdEnd, true); panel.NormalizeIndices(true, mdStart, ref startIndex, ref endIndex); int[] map = panel.Columns.DisplayIndexMap; for (int j = startIndex; j <= endIndex; j++) { GridColumn column = panel.Columns[map[j]]; if (j < mdStart || j > mdEnd) column.IsSelected = !column.IsSelected; } } } #endregion #region ProcessNonControlExtend private void ProcessNonControlExtend(GridPanel panel, bool extend) { int startIndex = 0; int endIndex = 0; if (GetSelectionIndicees(panel, panel.SelectionColumnAnchor, _HitItem, ref startIndex, ref endIndex, true) == true) { int[] map = panel.Columns.DisplayIndexMap; if (panel.OnlyColumnsSelected(startIndex, endIndex) == false) { if (extend == false) panel.ClearAll(); for (int i = 0; i < map.Length; i++) { int index = map[i]; GridColumn column = panel.Columns[index]; if (column.Visible == true) column.IsSelected = (i >= startIndex && i <= endIndex); } } } } #endregion #region GetSelectionIndicees private bool GetSelectionIndicees(GridPanel panel, object start, object end, ref int startIndex, ref int endIndex, bool reorder) { if (GetSelectionStartIndex(panel, start, ref startIndex) == false) return (false); if (GetSelectionEndIndex(panel, end, ref endIndex) == false) return (false); if (startIndex > endIndex) { if (start is ColumnGroupHeader) startIndex = ((ColumnGroupHeader)start).EndDisplayIndex; if (end is ColumnGroupHeader) endIndex = ((ColumnGroupHeader)end).StartDisplayIndex; if (reorder == true) { int tempIndex = startIndex; startIndex = endIndex; endIndex = tempIndex; } } return (true); } #endregion #region GetSelectionStartIndex private bool GetSelectionStartIndex(GridPanel panel, object item, ref int startIndex) { startIndex = -1; if (item is ColumnGroupHeader) startIndex = ((ColumnGroupHeader) item).StartDisplayIndex; else if (item is GridColumn) startIndex = panel.Columns.GetDisplayIndex(((GridColumn) item).ColumnIndex); return (startIndex >= 0); } #endregion #region GetSelectionEndIndex private bool GetSelectionEndIndex(GridPanel panel, object item, ref int endIndex) { endIndex = -1; if (item is ColumnGroupHeader) endIndex = ((ColumnGroupHeader)item).EndDisplayIndex; else if (item is GridColumn) endIndex = panel.Columns.GetDisplayIndex(((GridColumn) item).ColumnIndex); return (endIndex >= 0); } #endregion #endregion #endregion #region ColumnInResize private void ColumnInResize(Point pt, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { if (_Resizing == false) { StartResize(); } else { GridPanel panel = Parent as GridPanel; if (panel != null) { if (panel.ImmediateResize == false) ContinueResize(panel, pt); else ResizeColumn(panel, pt.X - MouseDownPoint.X); } } } } #endregion #endregion #region GroupHeaderMouseDownMove private bool GroupHeaderMouseDownMove(MouseEventArgs e, GridPanel panel) { ColumnGroupHeader cgh = (ColumnGroupHeader)_MouseDownHitItem; Rectangle r = ViewRect; if ((_MouseDownHitArea == HeaderArea.InResize) || (_MouseDownHitArea == HeaderArea.InRowHeaderResize) || (e.X >= r.X && e.X < r.Right) || (panel.IsSubPanel == false && IsGroupHeaderHFrozen(panel, cgh) == true)) { SuperGrid.DisableAutoScrolling(); switch (_MouseDownHitArea) { case HeaderArea.InContent: GroupHeaderInContent(e); break; } return (true); } return (false); } #region GroupHeaderInContent private void GroupHeaderInContent(MouseEventArgs e) { if (IsDesignerHosted == false) { if (e.Button == MouseButtons.Left) { GridPanel panel = Parent as GridPanel; if (panel != null) { if (DragStarted(panel, e) == false) { if (panel.ColumnDragBehavior == ColumnDragBehavior.ExtendClickBehavior) { switch (panel.ColumnGroupHeaderClickBehavior) { case ColumnHeaderClickBehavior.SortAndReorder: ProcessMove(e.Location); break; case ColumnHeaderClickBehavior.Select: if (_HitItem != _LastHitItem) ProcessExtendSelection(panel, true); break; } } } } } } } #endregion #endregion #endregion #region InternalMouseDown internal override void InternalMouseDown(MouseEventArgs e) { GridPanel panel = Parent as GridPanel; if (panel != null) { if (EndCurrentOp() == true) { _MouseDownPoint = e.Location; _MouseDownButtons = e.Button; _MouseDownHitItem = _HitItem; _MouseDownHitArea = _HitArea; _DragSelection = false; _DragStarted = false; if (_HitItem is GridColumn) ColumnMouseDown(e, panel); else if (_HitItem is ColumnGroupHeader) GroupHeaderMouseDown(e, panel); else RowHeaderMouseDown(e, panel); _lastSelectedItem = _HitItem; } SuperGrid.DoColumnHeaderMouseDownEvent(this, e); base.InternalMouseDown(e); } } #region EndCurrentOp private bool EndCurrentOp() { GridCell ecell = SuperGrid.EditorCell; if (ecell != null) { if (ecell.EndEdit() == false) { _MouseDownHitArea = HeaderArea.NoWhere; return (false); } } if (_Reordering == true || _Resizing == true) { StopResize(); StopReorder(); InvalidateRender(); } return (true); } #endregion #region ColumnMouseDown private void ColumnMouseDown(MouseEventArgs e, GridPanel panel) { GridColumn hitColumn = (GridColumn)_HitItem; if (_HitArea == HeaderArea.InContent) { Capture = true; ColumnInContentMouseDown(e, panel, hitColumn); } else if (_HitArea == HeaderArea.InMarkup) { InvalidateHeader(panel, hitColumn); } else { if (e.Button == MouseButtons.Left) { Capture = true; switch (_HitArea) { case HeaderArea.InResize: ColumnInResizeMouseDown(e, panel); break; case HeaderArea.InFilterMenu: ColumnInFilterMouseDown(panel, hitColumn); break; } } } } #region ColumnInContentMouseDown private void ColumnInContentMouseDown( MouseEventArgs e, GridPanel panel, GridColumn hitColumn) { _MouseDownDelta = e.X - hitColumn.BoundsRelative.X; if (panel.IsSubPanel == true || hitColumn.IsHFrozen == false) _MouseDownDelta += HScrollOffset; if (hitColumn.AllowSelection == true) { _LastHitItem = null; _Reordering = false; if (panel.ColumnHeaderClickBehavior == ColumnHeaderClickBehavior.Select) { if (hitColumn.IsSelected == false || ((Control.ModifierKeys & (Keys.Control | Keys.Shift)) != Keys.None)) { ExtendSelection(panel, true); } else { _DragSelection = true; } } else { InvalidateItem(panel, _MouseDownHitItem); } } } #region ExtendSelection private void ExtendSelection(GridPanel panel, bool capture) { if (capture == true) Capture = true; if (panel.SelectionColumnAnchor == null || (Control.ModifierKeys & Keys.Shift) != Keys.Shift) { panel.SelectionColumnAnchor = _MouseDownHitItem; } if ((Control.ModifierKeys & Keys.Control) == Keys.Control) { int startIndex = 0; int endIndex = 0; if (GetSelectionIndicees(panel, _MouseDownHitItem, _MouseDownHitItem, ref startIndex, ref endIndex, true) == true) { int[] map = panel.Columns.DisplayIndexMap; for (int i = startIndex; i <= endIndex; i++) { GridColumn column = panel.Columns[map[i]]; column.IsSelected = !column.IsSelected; } } } else { ProcessNonControlExtend(panel, false); } } #endregion #endregion #region ColumnInResizeMouseDown private void ColumnInResizeMouseDown(MouseEventArgs e, GridPanel panel) { GridColumn hitColumn = _HitItem as GridColumn; if (hitColumn != null) { Capture = true; _MouseDownDelta = e.X - hitColumn.BoundsRelative.X; if (panel.IsSubPanel == true || hitColumn.IsHFrozen == false) _MouseDownDelta += HScrollOffset; _Resizing = false; _LastHitItem = null; } } #endregion #region ColumnInFilterMouseDown private void ColumnInFilterMouseDown(GridPanel panel, GridColumn column) { ActivateFilterPopup(panel, column); } #endregion #endregion #region GroupHeaderMouseDown private void GroupHeaderMouseDown(MouseEventArgs e, GridPanel panel) { ColumnGroupHeader cgh = (ColumnGroupHeader)_HitItem; if (_HitArea == HeaderArea.InContent) { Capture = true; GroupHeaderInContentMouseDown(e, panel, cgh); } else if (_HitArea == HeaderArea.InMarkup) { InvalidateHeader(panel, cgh); } else { if (e.Button == MouseButtons.Left) { Capture = true; switch (_HitArea) { case HeaderArea.InResize: ColumnInResizeMouseDown(e, panel); break; } } } } #region GroupHeaderInContentMouseDown private void GroupHeaderInContentMouseDown( MouseEventArgs e, GridPanel panel, ColumnGroupHeader cgh) { _MouseDownDelta = e.X - cgh.BoundsRelative.X; if (panel.IsSubPanel == true || IsGroupHeaderHFrozen(panel, cgh) == false) _MouseDownDelta += HScrollOffset; if (cgh.AllowSelection == true) { _LastHitItem = null; _Reordering = false; if (panel.ColumnGroupHeaderClickBehavior == ColumnHeaderClickBehavior.Select) { if (IsGroupHeaderSelected(cgh) == false || ((Control.ModifierKeys & (Keys.Control | Keys.Shift)) != Keys.None)) { ExtendSelection(panel, true); } else { _DragSelection = true; } } else { InvalidateItem(panel, _MouseDownHitItem); } } } #endregion #endregion #region RowHeaderMouseDown private void RowHeaderMouseDown(MouseEventArgs e, GridPanel panel) { if (e.Button == MouseButtons.Left) { Capture = true; switch (_HitArea) { case HeaderArea.InRowHeader: InRowHeaderMouseDown(panel); break; case HeaderArea.InRowHeaderResize: InRowHeaderResizeMouseDown(); break; } } } #region InRowHeaderMouseDown private void InRowHeaderMouseDown(GridPanel panel) { if (panel.TopLeftHeaderSelectBehavior != TopLeftHeaderSelectBehavior.NoSelection) { bool select = (_SelectAllCount != panel.SelectionUpdateCount); if (select == true) { if (panel.MultiSelect == true) { panel.SelectAll(); } else if (panel.ActiveRow != null) { panel.ClearAll(); panel.ActiveRow.IsSelected = true; } } else { panel.ClearAll(); } } } #endregion #region InRowHeaderResizeMouseDown private void InRowHeaderResizeMouseDown() { Capture = true; _Resizing = false; } #endregion #endregion #endregion #region InternalMouseUp internal override void InternalMouseUp(MouseEventArgs e) { SuperGrid.DisableAutoScrolling(); GridPanel panel = Parent as GridPanel; if (panel != null) { if (_Reordering == true) { StopReorder(); if (_SeparatorColumn != null && _HitItem != _MouseDownHitItem) ReorderItem(panel); } else if (_Resizing == true && _ResizeColumn != null) { StopResize(); if (panel.ImmediateResize == false) ResizeColumn(panel, e.Location.X - MouseDownPoint.X); } else { if (_HitItem is GridColumn) ColumnMouseUp(e, panel); else if (_HitItem is ColumnGroupHeader) GroupHeaderMouseUp(e, panel); else RowHeaderMouseUp(e, panel); } } _MouseDownHitItem = null; SuperGrid.DoColumnHeaderMouseUpEvent(this, e); base.InternalMouseUp(e); } #region ColumnMouseUp private void ColumnMouseUp(MouseEventArgs e, GridPanel panel) { GridColumn hitColumn = (GridColumn)_HitItem; switch (_MouseDownHitArea) { case HeaderArea.InContent: case HeaderArea.InMarkup: if (hitColumn != null && hitColumn == _MouseDownHitItem) { if (SuperGrid.DoColumnHeaderClickEvent(panel, hitColumn, e) == false) { if (e.Button == MouseButtons.Left) { DoHeaderMouseUp(panel, panel.ColumnHeaderClickBehavior, hitColumn.HeaderTextMarkup, hitColumn); InvalidateHeader(panel, hitColumn); } } } break; } } #endregion #region GroupHeaderMouseUp private void GroupHeaderMouseUp(MouseEventArgs e, GridPanel panel) { ColumnGroupHeader cgh = (ColumnGroupHeader)_HitItem; switch (_MouseDownHitArea) { case HeaderArea.InContent: case HeaderArea.InMarkup: if (_HitItem == _MouseDownHitItem) { if (SuperGrid.DoColumnGroupHeaderClickEvent(panel, this, cgh, e) == false) { if (e.Button == MouseButtons.Left) { DoHeaderMouseUp(panel, panel.ColumnGroupHeaderClickBehavior, cgh.HeaderTextMarkup, panel.Columns.ColumnAtDisplayIndex(cgh.StartDisplayIndex)); InvalidateHeader(panel, cgh); } } } break; } } #endregion #region DoHeaderMouseUp private void DoHeaderMouseUp(GridPanel panel, ColumnHeaderClickBehavior cmode, BodyElement bodyElement, GridColumn hitColumn) { if (panel.FlushActiveRow() == true) { if (DoMarkupClick(bodyElement) == false) { if (_DragSelection == true) ExtendSelection(panel, false); if (cmode == ColumnHeaderClickBehavior.SortAndReorder && panel.IsSortable == true) SortColumn(panel, hitColumn); } } } #region DoMarkupClick private bool DoMarkupClick(BodyElement bodyElement) { if (bodyElement != null) { if (bodyElement.MouseOverElement != null) { bodyElement.Click(SuperGrid); SuperGrid.Cursor = Cursors.Default; return (true); } } return (false); } #endregion #endregion #region RowHeaderMouseUp private void RowHeaderMouseUp(MouseEventArgs e, GridPanel panel) { switch (_MouseDownHitArea) { case HeaderArea.InRowHeader: SuperGrid.DoColumnRowHeaderClickEvent(panel); break; case HeaderArea.InRowHeaderResize: if (_Resizing == true) { StopResize(); if (panel.ImmediateResize == false) ResizeRowHeader(panel, e.Location.X - MouseDownPoint.X); } break; } } #endregion #endregion #region InternalMouseDoubleClick internal override void InternalMouseDoubleClick(MouseEventArgs e) { GridColumn hitColumn = _HitItem as GridColumn; if (hitColumn != null) { if (SuperGrid.DoColumnHeaderDoubleClickEvent(hitColumn, e) == false) { switch (_HitArea) { case HeaderArea.InResize: if (hitColumn.GetAutoSizeMode() == ColumnAutoSizeMode.None) { RowScope scope = (GridPanel.VirtualMode == true || hitColumn.GridPanel.Rows.Count > 1000) ? RowScope.OnScreenRows : RowScope.AllRows; hitColumn.Width = Dpi.DescaleWidth(hitColumn.GetMaximumCellSize(scope, true).Width); } break; } } } else { if (_HitArea == HeaderArea.InRowHeader) SuperGrid.DoColumnRowHeaderDoubleClickEvent(GridPanel); } base.InternalMouseDoubleClick(e); } #endregion #endregion #region Column Reorder #region StartReorder private void StartReorder(Point pt) { if (_MouseDownHitItem != null && Math.Abs(MouseDownPoint.X - pt.X) > 5) { Capture = true; _Reordering = true; _SeparatorColumn = null; _HeaderFw = new FloatWindow(); _HeaderFw.Opacity = .3; _HeaderFw.Owner = SuperGrid.FindForm(); _HeaderFw.Paint += ColumnHeaderFwPaint; _SeparatorFw = new FloatWindow(); _SeparatorFw.Opacity = .5; _SeparatorFw.BackColor = Color.Black; _SeparatorFw.Owner = SuperGrid.FindForm(); } } #endregion #region StopReorder private void StopReorder() { _Reordering = false; if (_HeaderFw != null) { _HeaderFw.Close(); _HeaderFw.Paint -= ColumnHeaderFwPaint; _HeaderFw.Dispose(); _HeaderFw = null; } if (_SeparatorFw != null) { HideSeparator(); _SeparatorFw.Close(); _SeparatorFw.Dispose(); _SeparatorFw = null; } if (_MouseDownHitItem != null) InvalidateItem(GridPanel, _MouseDownHitItem); if (_HitItem != null) InvalidateItem(GridPanel, _HitItem); } #endregion #region ContinueReorder private void ContinueReorder(Point pt) { GridPanel panel = Parent as GridPanel; if (panel != null) { if (_HitItem != null && _MouseDownHitItem != null) { ReorderHeader(pt); if (ValidReorder() == true) { ReorderSeparator(pt); } else if (_SeparatorFw != null) { HideSeparator(); _SeparatorColumn = null; } } } } #region ValidReorder private bool ValidReorder() { if (IsItemHFrozen(_HitItem) == IsItemHFrozen(_MouseDownHitItem)) { object o1 = GetParent(_HitItem); object o2 = GetParent(_MouseDownHitItem); if (o1 is GridColumnHeader) o1 = null; if (o2 is GridColumnHeader) o2 = null; return (o1 == o2); } return (false); } #endregion #region ReorderHeader private void ReorderHeader(Point pt) { GridPanel panel = Parent as GridPanel; if (panel != null) { Rectangle r = GetReorderWindowBounds(panel, pt); if (r.Width <= 0 || r.Height <= 0) { _HeaderFw.Hide(); } else { r.Location = SuperGrid.PointToScreen(r.Location); Size size = _HeaderFw.Size; _HeaderFw.Bounds = r; if (_HeaderFw.Visible == false) _HeaderFw.Show(); else if (r.Size.Equals(size) == false) _HeaderFw.Refresh(); } } } #region GetReorderWindowBounds private Rectangle GetReorderWindowBounds(GridPanel panel, Point pt) { Rectangle r = GetReorderBounds(panel, _MouseDownHitItem); Rectangle t = SViewRect; r.X = (pt.X - _MouseDownDelta); int x = Math.Max(r.X, t.X); if (r.X < x) { _OrderTextOffset = r.X - x; r.X = x; r.Width += _OrderTextOffset; } else { _OrderTextOffset = 0; } int n = r.Right; x = Math.Min(n, t.Right); if (r.Right > x) r.Width -= (r.Right - x); if (r.Bottom > t.Bottom) r.Height -= (r.Bottom - t.Bottom); return (r); } #endregion #endregion #region ReorderSeparator private void ReorderSeparator(Point pt) { GridPanel panel = GridPanel; Rectangle r = GetReorderBounds(panel, _HitItem); Rectangle t = SViewRect; if (r.Right > t.Right) r.Width = t.Right - r.X; bool isRight = (pt.X > r.X + r.Width / 2); GridColumn column = GetSeparatorColumn(panel, isRight); if (_SeparatorColumn != column || _SeparatorIsRight != isRight) { _SeparatorColumn = column; _SeparatorIsRight = isRight; if (column != null) { r = GetReorderSeparatorBounds(panel, r, isRight); r.Location = SuperGrid.PointToScreen(r.Location); _SeparatorFw.Show(); _SeparatorFw.Bounds = r; _SeparatorFw.Size = r.Size; } else { HideSeparator(); } } else { if (_SeparatorColumn!= null) _SeparatorFw.Show(); } } #region HideSeparator private void HideSeparator() { if (_SeparatorFw != null) _SeparatorFw.Hide(); } #endregion #region GetSeparatorColumn private GridColumn GetSeparatorColumn(GridPanel panel, bool isRight) { if (_HitItem is GridColumn) return ((GridColumn) _HitItem); ColumnGroupHeader cgh = (ColumnGroupHeader)_HitItem; if (cgh != null) { GridColumnCollection columns = panel.Columns; int index = (isRight == true) ? cgh.EndDisplayIndex : cgh.StartDisplayIndex; return (columns[columns.DisplayIndexMap[index]]); } return (null); } #endregion #region GetReorderSeparatorBounds private Rectangle GetReorderSeparatorBounds( GridPanel panel, Rectangle r, bool isRight) { if (isRight == true) r.X = r.Right - (SeparatorWidth >> 1); else r.X -= (SeparatorWidth >> 1); r.Width = SeparatorWidth; if (r.X >= panel.BoundsRelative.Right - 2) r.X = panel.BoundsRelative.Right - 3; Rectangle t = SViewRect; if (r.Bottom > t.Bottom) r.Height -= (r.Bottom - t.Bottom); if (r.X < t.X) r.X = t.X; else if (r.Right > t.Right) r.X = t.Right - SeparatorWidth; return (r); } #endregion #endregion #endregion #region GetReorderBounds private Rectangle GetReorderBounds(GridPanel panel, object item) { Rectangle r = BoundsRelative; if (item is GridColumn) { GridColumn column = (GridColumn)item; int index = panel.Columns.GetDisplayIndex(column); ColumnGroupHeader cgh = GetParentHeader(index); if (cgh != null) r.Y = r.Bottom - (cgh.Size.Height - cgh.BoundsRelative.Height); r.Height = (panel.BoundsRelative.Height - (r.Y - panel.BoundsRelative.Y)); r.X = column.BoundsRelative.X; r.Width = column.BoundsRelative.Width; if (panel.IsSubPanel == true || column.IsHFrozen == false) r.X -= HScrollOffset; if (IsVFrozen == false) r.Y -= VScrollOffset; return (r); } if (item is ColumnGroupHeader) { ColumnGroupHeader cgh = (ColumnGroupHeader)item; r.Y = r.Bottom - cgh.Size.Height; r.Height = (panel.BoundsRelative.Height - (r.Y - panel.BoundsRelative.Y)); r.X = cgh.BoundsRelative.X; r.Width = cgh.BoundsRelative.Width; if (panel.IsSubPanel == true || IsGroupHeaderHFrozen(panel, cgh) == false) r.X -= HScrollOffset; if (IsVFrozen == false) r.Y -= VScrollOffset; } return (r); } #endregion #region ReorderItem private void ReorderItem(GridPanel panel) { if (_MouseDownHitItem is GridColumn) ReorderColumn(panel); if (_MouseDownHitItem is ColumnGroupHeader) ReorderGroupHeader(panel); } #region ReorderColumn private void ReorderColumn(GridPanel panel) { GridColumn hitColumn = (GridColumn)_MouseDownHitItem; GridColumnCollection columns = _Columns; int[] map = columns.DisplayIndexMap; int curIndex = columns.GetDisplayIndex(hitColumn); int sepIndex = columns.GetDisplayIndex(_SeparatorColumn); if (curIndex > sepIndex && _SeparatorIsRight == true && sepIndex < map.Length - 1) sepIndex++; else if (curIndex < sepIndex && _SeparatorIsRight == false && sepIndex > 0) sepIndex--; if (sepIndex != curIndex) { ColumnGroupHeader parent = GetParent(hitColumn) as ColumnGroupHeader; int[] dmap = new int[map.Length]; if (sepIndex < curIndex) { for (int i = curIndex; i > sepIndex; i--) { map[i] = map[i - 1]; dmap[i - 1] = 1; } } else { for (int i = curIndex; i < sepIndex; i++) { map[i] = map[i + 1]; dmap[i + 1] = -1; } } map[sepIndex] = hitColumn.ColumnIndex; dmap[curIndex] = sepIndex - curIndex; for (int i = 0; i < map.Length; i++) columns[map[i]].DisplayIndex = i; UpdateGroupHeaderRanges(parent != null ? parent.GroupHeaders : GroupHeaders, dmap); SuperGrid.UpdateStyleCount(); SuperGrid.PrimaryGrid.InvalidateRender(); SuperGrid.DoColumnMovedEvent(panel, hitColumn); } } #endregion #region ReorderGroupHeader private void ReorderGroupHeader(GridPanel panel) { ColumnGroupHeader cgh = (ColumnGroupHeader)_MouseDownHitItem; GridColumnCollection columns = _Columns; int[] map = columns.DisplayIndexMap; int curStartIndex = cgh.StartDisplayIndex; int curEndIndex = cgh.EndDisplayIndex; int sepIndex = columns.GetDisplayIndex(_SeparatorColumn); if (curStartIndex > sepIndex && _SeparatorIsRight == true && sepIndex < map.Length - 1) sepIndex++; else if (curEndIndex < sepIndex && _SeparatorIsRight == false && sepIndex > 0) sepIndex--; if (sepIndex != curStartIndex && sepIndex != curEndIndex) { ColumnGroupHeader parent = GetParent(cgh) as ColumnGroupHeader; int n = curEndIndex - curStartIndex + 1; int[] temp = new int[n]; int[] dmap = new int[map.Length]; for (int i = 0; i < n; i++) temp[i] = map[curStartIndex + i]; for (int i = 0; i < dmap.Length; i++) dmap[i] = 0; if (sepIndex < curStartIndex) { for (int i = curStartIndex - 1; i >= sepIndex; i--) { map[i + n] = map[i]; dmap[i] = n; } for (int i = 0; i < n; i++) map[sepIndex + i] = temp[i]; for (int i = curStartIndex; i <= curEndIndex; i++) dmap[i] = sepIndex - curStartIndex; } else { for (int i = curEndIndex + 1; i <= sepIndex; i++) { map[i - n] = map[i]; dmap[i] = -n; } for (int i = 0; i < n; i++) map[sepIndex - n + i + 1] = temp[i]; for (int i = curStartIndex; i <= curEndIndex; i++) dmap[i] = sepIndex - curEndIndex; } for (int i = 0; i < map.Length; i++) columns[map[i]].DisplayIndex = i; UpdateGroupHeaderRanges(parent != null ? parent.GroupHeaders : cgh.Collection, dmap); SuperGrid.UpdateStyleCount(); SuperGrid.PrimaryGrid.InvalidateRender(); for (int i = curStartIndex; i <= curEndIndex; i++) SuperGrid.DoColumnMovedEvent(panel, columns[map[i]]); } } #endregion #region UpdateGroupHeaderRanges private void UpdateGroupHeaderRanges(ColumnGroupHeaderCollection csc, int[] dmap) { foreach (ColumnGroupHeader cgh in csc) { if (cgh.Visible == true) { UpdateGroupHeaderRanges(cgh.GroupHeaders, dmap); cgh.StartDisplayIndex += dmap[cgh.StartDisplayIndex]; cgh.EndDisplayIndex += dmap[cgh.EndDisplayIndex]; } } } #endregion #endregion #region ColumnHeaderFwPaint void ColumnHeaderFwPaint(object sender, PaintEventArgs e) { GridPanel panel = GridPanel; if (_MouseDownHitItem is GridColumn) { GridColumn mouseDownHitColumn = (GridColumn)_MouseDownHitItem; Rectangle r = mouseDownHitColumn.BoundsRelative; r.Y = 0; r.X = _OrderTextOffset; r.Height = e.ClipRectangle.Height; RenderColumnHeader(e.Graphics, panel, mouseDownHitColumn, r, false); r.Width--; r.Height--; e.Graphics.DrawRectangle(Pens.DimGray, r); } else if (_MouseDownHitItem is ColumnGroupHeader) { ColumnGroupHeader cgh = (ColumnGroupHeader)_MouseDownHitItem; Rectangle r = cgh.BoundsRelative; r.Y = 0; r.X = _OrderTextOffset; r.Height = e.ClipRectangle.Height; RenderGroupHeader(e.Graphics, panel, cgh, r); r.Width--; r.Height--; e.Graphics.DrawRectangle(Pens.DimGray, r); } } #endregion #region SortColumn internal void SortColumn(GridPanel panel, GridColumn column) { if (panel.IsSortable == true) { if (column.IsGroupColumn == true) { column.GroupDirection = ToggleSortDirection(panel, column.GroupDirection, column.SortCycle); SuperGrid.DoSortChangedEvent(panel); } else if (column.ColumnSortMode != ColumnSortMode.None) { SortDirection sortDirection = ToggleSortDirection(panel, column.SortDirection, column.SortCycle); if (column.ColumnSortMode == ColumnSortMode.Multiple && ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)) { panel.AddSort(column, sortDirection); } else { if (panel.SortColumns.Count > 1) sortDirection = SortDirection.Ascending; panel.SetSort(column, sortDirection); } SuperGrid.DoSortChangedEvent(panel); } else { InvalidateHeader(panel, column); } } else { InvalidateHeader(panel, column); } } #region ToggleSortDirection private SortDirection ToggleSortDirection( GridPanel panel, SortDirection dir, SortCycle sortCycle) { if (dir == SortDirection.Ascending) return (SortDirection.Descending); if (dir == SortDirection.None) return (SortDirection.Ascending); if (sortCycle == SortCycle.NotSet) { sortCycle = panel.SortCycle; if (sortCycle == SortCycle.NotSet) sortCycle = SortCycle.AscDesc; } return (sortCycle == SortCycle.AscDescNone ? SortDirection.None : SortDirection.Ascending); } #endregion #endregion #endregion #region Column Resize #region StartResize private void StartResize() { GridPanel panel = Parent as GridPanel; if (panel != null) { _ResizeColumn = _MouseDownHitItem as GridColumn; if (_ResizeColumn != null) { _Resizing = true; _ResizeWidth = _ResizeColumn.Size.Width; _HitItem = _ResizeColumn; _HitArea = HeaderArea.InResize; if (panel.ImmediateResize == false) { _SeparatorFw = new FloatWindow(); _SeparatorFw.Opacity = .5; _SeparatorFw.BackColor = Color.Black; _SeparatorFw.Owner = SuperGrid.FindForm(); } } } } #endregion #region StopResize private void StopResize() { _Resizing = false; if (_SeparatorFw != null) { HideSeparator(); _SeparatorFw.Close(); _SeparatorFw.Dispose(); _SeparatorFw = null; } } #endregion #region ContinueResize private void ContinueResize(GridPanel panel, Point pt) { Rectangle r = panel.BoundsRelative; r.Y = BoundsRelative.Y; if (panel.IsSubPanel == true) r.Y -= VScrollOffset; r.X -= HScrollOffset; if (pt.X > r.X) { Rectangle t = _ResizeColumn.BoundsRelative; t.X -= HScrollOffset; int width = pt.X - t.X; int n = Dpi.Width(_ResizeColumn.MinimumWidth); if (width < n) pt.X = t.X + n; if (pt.X >= SuperGrid.PrimaryGrid.BoundsRelative.Right - Dpi.Width2) { HideSeparator(); } else { if (pt.X == panel.BoundsRelative.Right - 1) pt.X -= 1; r.X = pt.X; r.Width = Dpi.Width(SeparatorWidth); r.Height -= (BoundsRelative.Y - panel.BoundsRelative.Y); t = SViewRect; if (r.Bottom > t.Bottom) r.Height -= (r.Bottom - t.Bottom); r.Location = SuperGrid.PointToScreen(r.Location); _SeparatorFw.Show(); _SeparatorFw.Bounds = r; _SeparatorFw.Size = r.Size; } } } #endregion #region ResizeColumn #region ResizeColumn private void ResizeColumn(GridPanel panel, int width) { ColumnAutoSizeMode autoSizeMode = _ResizeColumn.GetAutoSizeMode(); if (autoSizeMode == ColumnAutoSizeMode.None) ResizeNoneColumn(panel, width); else if (autoSizeMode == ColumnAutoSizeMode.Fill) ResizeFillColumn(panel, width); } #endregion #region ResizeNoneColumn private void ResizeNoneColumn(GridPanel panel, int width) { int newWidth = _ResizeWidth + width; int n = Dpi.Width(_ResizeColumn.MinimumWidth); if (newWidth < n) newWidth = n; if (_ResizeColumn.ResizeMode == ColumnResizeMode.MoveFollowingElements) { _ResizeColumn.Width = Dpi.DescaleWidth(newWidth); } else if (_ResizeColumn.ResizeMode == ColumnResizeMode.MaintainTotalWidth) { GridColumn ncolumn = panel.Columns.GetNextVisibleColumn(_ResizeColumn); if ((ncolumn == null) || (ncolumn.GetAutoSizeMode() != ColumnAutoSizeMode.None)) { _ResizeColumn.Width = Dpi.DescaleWidth(newWidth); } else { int twidth = _ResizeColumn.Size.Width + ncolumn.Size.Width; int nwidth = twidth - newWidth; int n2 = Dpi.Width(ncolumn.MinimumWidth); if (nwidth < n2) nwidth = n2; newWidth = twidth - nwidth; _ResizeColumn.Width = Dpi.DescaleWidth(newWidth); ncolumn.Width = Dpi.DescaleWidth(nwidth); } } } #endregion #region ResizeFillColumn private void ResizeFillColumn(GridPanel panel, int width) { int fillWeight = 0; int fillWidth = 0; GridColumnCollection columns = _Columns; int colDisplayIndex = columns.GetDisplayIndex(_ResizeColumn); int[] map = columns.DisplayIndexMap; for (int i = 0; i < map.Length; i++) { int index = map[i]; GridColumn column = columns[index]; if (column.Visible == true) { if (column.GetAutoSizeMode() == ColumnAutoSizeMode.Fill) { fillWidth += column.Size.Width; if (i != colDisplayIndex) fillWeight += column.FillWeight; } } } if (fillWidth > 0 && fillWeight > 0) { int nw = _ResizeWidth + width; int newFillWidth = fillWidth - nw; for (int i = 0; i < map.Length; i++) { int index = map[i]; GridColumn column = columns[index]; if (column.Visible == true) { if (column.GetAutoSizeMode() == ColumnAutoSizeMode.Fill) { float colWidth; if (i != colDisplayIndex) colWidth = (int)(newFillWidth * (float)column.FillWeight / fillWeight); else colWidth = nw; int n = Dpi.Width(column.MinimumWidth); if (colWidth < n) colWidth = n; column.FillWeight = (int)((colWidth * 1000) / fillWidth); } } } panel.SuperGrid.Invalidate(); } } #endregion #endregion #endregion #region RowHeader Resize #region ContinueRowHeaderResize private void ContinueRowHeaderResize(GridPanel panel, Point pt) { Rectangle r = panel.BoundsRelative; r.Y = BoundsRelative.Y; if (panel.IsSubPanel == true) r.Y -= VScrollOffset; r.X -= HScrollOffset; if (pt.X > r.X) { int width = pt.X - r.X; if (width < 5) pt.X = r.X + 5; if (pt.X >= SuperGrid.PrimaryGrid.BoundsRelative.Right - 2) { HideSeparator(); } else { if (pt.X == panel.BoundsRelative.Right - 1) pt.X--; r.X = pt.X; r.Width = SeparatorWidth; r.Height -= (BoundsRelative.Y - panel.BoundsRelative.Y); Rectangle t = SViewRect; if (r.Bottom > t.Bottom) r.Height -= (r.Bottom - t.Bottom); r.Location = SuperGrid.PointToScreen(r.Location); _SeparatorFw.Show(); _SeparatorFw.Bounds = r; _SeparatorFw.Size = r.Size; } } } #endregion #region ResizeRowHeader private void ResizeRowHeader(GridPanel panel, int width) { Rectangle t = panel.ViewRect; int n = Math.Max(5, _ResizeWidth + width); if (t.Right - 10 < n) n = t.Right - 10; n = Dpi.DescaleWidth(n); if (panel.RowHeaderWidth != n) { panel.RowHeaderWidth = n; panel.SuperGrid.Invalidate(); SuperGrid.DoRowHeaderResizedEvent(panel); } } #endregion #endregion #region ActivateFilterPopup internal void ActivateFilterPopup(GridPanel panel, GridColumn column) { if (_FilterMenu != null) _FilterMenu.Dispose(); _FilterMenu = new FilterPopup(panel); _LockedColumn = true; _HitArea = HeaderArea.NoWhere; _FilterMenu.ActivatePopup(column, ResetColumnState); } #endregion #region DeactivateFilterPopup internal void DeactivateFilterPopup(GridPanel panel, GridColumn column) { FilterPopup fm = _FilterMenu; if (fm != null) fm.DeactivatePopup(); } #endregion #region GetHitArea /// /// Returns the ColumnHeader hit area /// and column for the given Point /// /// /// ///HeaderArea public HeaderArea GetHitArea(Point pt, ref GridColumn column) { object hitItem = null; HeaderArea area = GetHitArea(pt, ref hitItem, false); column = hitItem as GridColumn; return (area); } /// /// Returns the ColumnHeader hit area /// and hit object for the given Point /// /// /// /// public HeaderArea GetHitArea(Point pt, ref object hitItem) { return (GetHitArea(pt, ref hitItem, false)); } private HeaderArea GetHitArea( Point pt, ref object hitItem, bool isMouseDown) { GridPanel panel = Parent as GridPanel; if (panel != null) { GridElement hitObject = GetHitObject(panel, pt, isMouseDown); if (hitObject == this) return (GetHeaderHitArea(panel, pt, ref hitItem, isMouseDown)); if (hitObject == panel.GroupByRow) return (HeaderArea.InGroupBox); } return (HeaderArea.NoWhere); } #region GetHitObject private GridElement GetHitObject( GridPanel panel, Point pt, bool isMouseDown) { if (isMouseDown == true && panel.GroupByRow.Visible == true) { if (panel.GroupByRow.Bounds.Contains(pt) == true) return (panel.GroupByRow); } if (Capture == true || Bounds.Contains(pt) == true) return (this); return (null); } #endregion #region GetHeaderHitArea private HeaderArea GetHeaderHitArea(GridPanel panel, Point pt, ref object hitItem, bool isMouseDown) { hitItem = null; HeaderArea area = GetRowHeaderArea(panel, pt); if (area != HeaderArea.NoWhere) return (area); area = GetGroupHeaderArea(panel, pt, ref hitItem); if (area != HeaderArea.NoWhere) return (area); GridColumn column = GetHitColumn(panel, pt, isMouseDown, false); area = GetHeaderArea(panel, pt, ref column); hitItem = column; return (area); } #region GetGroupHeaderArea private HeaderArea GetGroupHeaderArea(GridPanel panel, Point pt, ref object hitItem) { ColumnGroupHeader cgh = GetHitGroupHeader(panel, pt, _GroupHeaders); if (cgh != null) { if (GetShowRootColumnHeaders(cgh) == false) { GridColumn coll = GetHitColumn(panel, pt, false, true); if (coll != null) { HeaderArea area = GetHeaderArea(panel, pt, ref coll); if (area == HeaderArea.InResize) { hitItem = coll; return (area); } } } hitItem = cgh; if (IsMouseDown == false) { int[] map = panel.Columns.DisplayIndexMap; Rectangle r = GetSubScrollBounds(panel, cgh); if (pt.X < r.Left + 3 && pt.X >= r.Left) { if ((uint)cgh.StartDisplayIndex < map.Length) { GridColumn column = panel.Columns[map[cgh.StartDisplayIndex]]; if (InLeftResizeArea(ref column, panel) == true) { hitItem = column; return (HeaderArea.InResize); } } } if ((pt.X > r.Right - 5) && (pt.X < r.Right + 3)) { if ((uint)cgh.EndDisplayIndex < map.Length) { GridColumn column = panel.Columns[map[cgh.EndDisplayIndex]]; if (InRightResizeArea(ref column, panel) == true) { hitItem = column; return (HeaderArea.InResize); } } } } if (cgh.AllowSelection == true) return (HeaderArea.InContent); return (HeaderArea.NoWhere); } return (HeaderArea.NoWhere); } #endregion #region GetHitGroupHeader private ColumnGroupHeader GetHitGroupHeader( GridPanel panel, Point pt, ColumnGroupHeaderCollection csc) { if (csc != null) { foreach (ColumnGroupHeader cgh in csc) { if (cgh.Visible == true) { Rectangle r = GetSubScrollBounds(panel, cgh); if (r.Contains(pt) == true) return (cgh); ColumnGroupHeader csh2 = GetHitGroupHeader(panel, pt, cgh.GroupHeaders); if (csh2 != null) return (csh2); } } } return (null); } #endregion #region GetRowHeaderArea private HeaderArea GetRowHeaderArea(GridPanel panel, Point pt) { Rectangle r = GetRowHeaderBounds(panel); r.Width += Dpi.Width2; if (r.Contains(pt) == true) { if (Capture == true) return (_HitArea); r.Width -= Dpi.Width2; if (panel.AllowRowHeaderResize == true) { if (pt.X >= r.Right - Dpi.Width5) return (HeaderArea.InRowHeaderResize); } return (HeaderArea.InRowHeader); } return (HeaderArea.NoWhere); } #endregion #region GetHitColumn /// /// Gets the associated column at the given location /// /// /// /// public GridColumn GetHitColumn(int x, int y) { return (GetHitColumn(new Point(x, y))); } /// /// Gets the associated column at the given point /// /// /// public GridColumn GetHitColumn(Point pt) { GridPanel panel = GridPanel; if (panel != null) return (GetHitColumn(panel, pt, false, false)); return (null); } private GridColumn GetHitColumn( GridPanel panel, Point pt, bool isMouseDown, bool limit) { int dy = (isMouseDown == true) ? 50 : 0; GridColumnCollection columns = _Columns; foreach (GridColumn column in columns) { if (column.Visible == true) { Rectangle r = GetBounds(panel, column); if (pt.X >= r.Left && pt.X < r.Right) { int top = limit ? r.Bottom - 10 : r.Top; if (pt.Y >= top && pt.Y < r.Bottom + dy) return (column); } } } return (null); } #endregion #region GetHeaderArea private HeaderArea GetHeaderArea(GridPanel panel, Point pt, ref GridColumn column) { GridColumn hcolumn = column; if (column == null) column = panel.Columns.LastVisibleColumn; if (column != null) { Rectangle r = column.BoundsRelative; if (IsVFrozen == false) r.Y -= VScrollOffset; if (panel.IsSubPanel == true || column.IsHFrozen == false) r.X -= HScrollOffset; if (pt.X < r.Left + 3 && pt.X >= r.Left) { if (InLeftResizeArea(ref column, panel) == true) return (HeaderArea.InResize); } if ((pt.X > r.Right - 5) && (pt.X < r.Right + 3)) { if (InRightResizeArea(ref column, panel) == true) return (HeaderArea.InResize); } if (column.FilterImageBounds.IsEmpty == false) { Rectangle t = GetScrollBounds( panel, column, column.FilterImageBounds); t.Inflate(2, 2); if (t.Contains(pt) == true) return (HeaderArea.InFilterMenu); } column = hcolumn; if (hcolumn != null) { if (column.AllowSelection == true) return (HeaderArea.InContent); return (HeaderArea.NoWhere); } } return (HeaderArea.InWhitespace); } #region InLeftResizeArea private bool InLeftResizeArea(ref GridColumn column, GridPanel panel) { GridColumn pcolumn = panel.Columns.GetPrevVisibleColumn(column); if (pcolumn != null) { if (pcolumn.CanResize == true && pcolumn.ResizeMode != ColumnResizeMode.None) { column = pcolumn; return (true); } } return (false); } #endregion #region InRightResizeArea private bool InRightResizeArea(ref GridColumn column, GridPanel panel) { GridColumn nColumn = panel.Columns.GetNextVisibleColumn(column); if (nColumn != null && nColumn.Size.Width < 5) { if (nColumn.CanResize == true && nColumn.ResizeMode != ColumnResizeMode.None) column = nColumn; } if (column.CanResize == true && column.ResizeMode != ColumnResizeMode.None) return (true); return (false); } #endregion #endregion #endregion #endregion #region GetParent /// ///Gets the object that is the "parent" of the given item ///(either a GridColumn or ColumnGroupHeader). /// /// ///Parent or null public object GetParent(object item) { if (item is GridColumn) return (GetParentHeader((GridColumn) item)); ColumnGroupHeader cgh = item as ColumnGroupHeader; if (cgh != null) return (cgh.Collection.Parent); return (null); } #endregion #region GetParentHeader /// ///Gets the object that is the "parent" of the given column. /// /// ///parent or null public object GetParentHeader(GridColumn column) { int index = GridPanel.Columns.GetDisplayIndex(column); return (GetParentHeader(index)); } /// ///Gets the ColumnGroupHeader that is the "parent" of the column at ///the given DISPLAY index. /// ///DISPLAY INDEX ///parent object or null public ColumnGroupHeader GetParentHeader(int displayIndex) { ColumnGroupHeader tcsh = GetColumnGroupHeader(GroupHeaders, displayIndex); if (tcsh != null) { while (tcsh.GroupHeaders != null) { ColumnGroupHeader fcsh = GetColumnGroupHeader(tcsh.GroupHeaders, displayIndex); if (fcsh == null || fcsh.Visible == false) break; tcsh = fcsh; } } return (tcsh); } #endregion #region GetColumnGroupHeader internal ColumnGroupHeader GetColumnGroupHeader(int index) { return (GetColumnGroupHeader(GroupHeaders, index)); } private ColumnGroupHeader GetColumnGroupHeader(IEnumerable csc, int index) { if (csc != null) { foreach (ColumnGroupHeader cgh in csc) { if (cgh.Contains(index)) return (cgh.Visible == true ? cgh : null); } } return (null); } #endregion #region UpdateImageBounds internal void UpdateImageBounds(GridPanel panel, GridColumn column) { Rectangle r = GetColumnHeaderBounds(panel, column); if (column.AdjustSortImagePositionByMargin == true) { VisualStyle style = GetEffectiveStyle(column); r.X += (style.BorderThickness.Left + style.Margin.Left); r.Width -= (style.BorderThickness.Horizontal + style.Margin.Horizontal); r.Y += (style.BorderThickness.Top + style.Margin.Top); r.Height -= (style.BorderThickness.Vertical + style.Margin.Vertical); } r.Inflate(-3, -3); r.Width--; Alignment sortAlignment = (_SortImageAlignment == Alignment.NotSet) ? Alignment.TopCenter : _SortImageAlignment; Alignment filterAlignment = (_FilterImageAlignment == Alignment.NotSet) ? Alignment.MiddleLeft : _FilterImageAlignment; Rectangle rt = r; column.SortImageBounds = Rectangle.Empty; column.FilterImageBounds = Rectangle.Empty; Image sortImage = GetColumnSortImage(panel, column); if (sortImage != null) { Rectangle t = GetImageBounds(sortImage, sortAlignment, ref r); column.SortImageBounds = t; } Image filterImage = GetColumnFilterImage(column); if (filterImage != null) { Rectangle t; if (sortImage != null && filterAlignment == sortAlignment) { t = GetImageBounds(filterImage, filterAlignment, ref r); switch (filterAlignment) { case Alignment.TopCenter: case Alignment.MiddleCenter: case Alignment.BottomCenter: t.X = rt.X + (r.Width - (sortImage.Width + filterImage.Width)) / 2 + sortImage.Width; break; case Alignment.TopLeft: case Alignment.MiddleLeft: case Alignment.BottomLeft: break; } } else { t = GetImageBounds(filterImage, filterAlignment, ref rt); r.Intersect(rt); } column.FilterImageBounds = t; } } #endregion #region GetColumnHeaderBounds private Rectangle GetColumnHeaderBounds(GridPanel panel, GridColumn column) { Rectangle r = GetRelativeBounds(panel, column); r.X = column.BoundsRelative.X; r.Width = column.BoundsRelative.Width; ColumnGroupHeader cgh = GetParentHeader(panel.Columns.GetDisplayIndex(column.ColumnIndex)); if (cgh != null) { int n = cgh.Size.Height - cgh.BoundsRelative.Height; r.Y = r.Bottom - n; r.Height = n; } return (r); } #endregion #region GetRelativeSubSize internal int GetRelativeSubSize(ColumnGroupHeader cgh, int index) { int n = cgh.BoundsRelative.Height; foreach (ColumnGroupHeader sub in cgh.GroupHeaders) { if (sub.Contains(index) == true) n += GetRelativeSubSize(sub, index); } return (n); } #endregion #region GetRowHeaderBounds private Rectangle GetRowHeaderBounds(GridPanel panel) { if (panel.ShowRowHeaders == true) { Rectangle r = Bounds; r.Width = panel.RowHeaderWidthEx; Rectangle p = panel.PanelBounds; if (r.Y < p.Y) { r.Height -= (p.Y - r.Y + 1); r.Y = p.Y + 1; } return (r); } return (Rectangle.Empty); } #endregion #region Style support #region GroupHeader Style support #region InvalidateStyle /// ///Invalidates the cached Style ///definition for all defined StyleTypes /// public void InvalidateStyle() { GridColumnCollection columns = GridPanel.Columns; foreach (GridColumn column in columns) column.InvalidateStyle(); InvalidateStyle(GroupHeaders); } /// ///Invalidates the cached Style ///definition for all GroupHeader defined StyleTypes /// /// public void InvalidateStyle(ColumnGroupHeader cgh) { if (cgh.EffectiveStyles != null) { cgh.EffectiveStyles.Dispose(); cgh.EffectiveStyles = null; } InvalidateStyle(cgh.GroupHeaders); } private void InvalidateStyle(IEnumerable groups) { foreach (ColumnGroupHeader cgh in groups) InvalidateStyle(cgh); } /// ///Invalidate the cached Style ///definition for the given StyleType /// /// public void InvalidateStyle(StyleType type) { GridColumnCollection columns = GridPanel.Columns; foreach (GridColumn column in columns) column.InvalidateStyle(type); InvalidateStyle(GroupHeaders, type); } /// ///Invalidate the cached Style ///definition for the given GroupHeader StyleType /// /// /// public void InvalidateStyle(ColumnGroupHeader cgh, StyleType type) { if (cgh.EffectiveStyles != null) { cgh.EffectiveStyles[type].Dispose(); cgh.EffectiveStyles[type] = null; } InvalidateStyle(cgh.GroupHeaders, type); } private void InvalidateStyle(IEnumerable groups, StyleType type) { foreach (ColumnGroupHeader cgh in groups) InvalidateStyle(cgh, type); } #endregion #region GetSizingStyle private ColumnHeaderVisualStyle GetSizingStyle(GridPanel panel, ColumnGroupHeader cgh) { StyleType style = panel.GetSizingStyle(); if (style == StyleType.NotSet) style = StyleType.Default; return (GetEffectiveStyle(cgh, style)); } #endregion #region GetGroupHeaderStyleState private StyleState GetGroupHeaderStyleState(ColumnGroupHeader cgh) { StyleState state = StyleState.Default; if (_Reordering == true) { if (cgh == _MouseDownHitItem) state |= StyleState.MouseOver; } else if (_HitItem == cgh) { state |= StyleState.MouseOver; } if (IsGroupHeaderSelected(cgh) == true) state |= StyleState.Selected; if (IsGroupHeaderReadOnly(cgh) == true) state |= StyleState.ReadOnly; return (state); } #endregion #region GetEffectiveStyle /// /// GetEffectiveStyle /// /// /// public ColumnHeaderVisualStyle GetEffectiveStyle(ColumnGroupHeader cgh) { StyleState styleState = GetGroupHeaderStyleState(cgh); ColumnHeaderVisualStyle style = GetEffectiveStyle(cgh, styleState); return (style); } /// ///Gets the EffectiveStyle for the given StyleState /// /// /// /// public ColumnHeaderVisualStyle GetEffectiveStyle(ColumnGroupHeader cgh, StyleState cellState) { StyleType type = GetStyleType(cellState); return (GetEffectiveStyle(cgh, type)); } internal ColumnHeaderVisualStyle GetEffectiveStyle(ColumnGroupHeader cgh, StyleType sizingStyle) { return (GetGroupHeaderStyle(cgh, sizingStyle)); } #region GetGroupHeaderStyle internal ColumnHeaderVisualStyle GetGroupHeaderStyle(ColumnGroupHeader cgh, StyleType e) { ValidateGroupHeaderStyle(cgh); if (cgh.EffectiveStyles == null) cgh.EffectiveStyles = new ColumnHeaderVisualStyles(); if (cgh.EffectiveStyles.IsValid(e) == false) { GridPanel panel = GridPanel; ColumnHeaderVisualStyle style = new ColumnHeaderVisualStyle(); StyleType[] css = style.GetApplyStyleTypes(e); if (css != null) { ColumnGroupHeader pcgh = GetParent(cgh) as ColumnGroupHeader; if (pcgh != null) { if (GetAutoApplyGroupColor(cgh) != true) pcgh = null; } foreach (StyleType cs in css) { style.ApplyStyle(SuperGrid.BaseVisualStyles.ColumnHeaderStyles[cs]); style.ApplyStyle(SuperGrid.DefaultVisualStyles.ColumnHeaderStyles[cs]); style.ApplyStyle(GridPanel.DefaultVisualStyles.ColumnHeaderStyles[cs]); style.ApplyStyle(cgh.HeaderStyles[cs]); if (pcgh != null) { ColumnHeaderVisualStyle gstyle = GetEffectiveStyle(pcgh, cs); if (gstyle.Background != null) { if (cgh.HeaderStyles[cs].Background == null || cgh.HeaderStyles[cs].Background.IsEmpty) style.Background = gstyle.Background.Copy(); } if (gstyle.TextColor.IsEmpty == false) { if (cgh.HeaderStyles[cs].TextColor.IsEmpty) style.TextColor = gstyle.TextColor; } } } } SuperGrid.DoGetColumnGroupHeaderStyleEvent(panel, cgh, e, ref style); if (style.Background == null || style.Background.IsEmpty == true) style.Background = new Background(Color.White); if (style.Font == null) style.Font = SystemFonts.DefaultFont; cgh.EffectiveStyles[e] = style; } return (cgh.EffectiveStyles[e]); } #region ValidateGroupHeaderStyle private void ValidateGroupHeaderStyle(ColumnGroupHeader cgh) { if (cgh.StyleUpdateCount != SuperGrid.StyleUpdateCount) { if (cgh.EffectiveStyles != null) { cgh.EffectiveStyles.Dispose(); cgh.EffectiveStyles = null; } cgh.StyleUpdateCount = SuperGrid.StyleUpdateCount; } } #endregion #endregion #endregion #endregion #region ColumnHeader Style support #region GetSizingStyle private ColumnHeaderVisualStyle GetSizingStyle(GridPanel panel, GridColumn column) { StyleType style = panel.GetSizingStyle(); if (style == StyleType.NotSet) style = StyleType.Default; return (GetEffectiveStyle(column, style)); } #endregion #region GetStyleState private StyleState GetStyleState(GridColumn column, bool selected) { StyleState state = StyleState.Default; if (_Reordering == true) { if (column == _MouseDownHitItem) state |= StyleState.MouseOver; } else if (_HitItem == column) { state |= StyleState.MouseOver; } if (selected == true) state |= StyleState.Selected; if (column.IsReadOnly == true) state |= StyleState.ReadOnly; return (state); } #endregion #region GetStyleType private StyleType GetStyleType(StyleState state) { switch (state) { case StyleState.MouseOver: return (StyleType.MouseOver); case StyleState.Selected: return (StyleType.Selected); case StyleState.Selected | StyleState.MouseOver: return (StyleType.SelectedMouseOver); case StyleState.ReadOnly: return (StyleType.ReadOnly); case StyleState.ReadOnly | StyleState.MouseOver: return (StyleType.ReadOnlyMouseOver); case StyleState.ReadOnly | StyleState.Selected: return (StyleType.ReadOnlySelected); case StyleState.ReadOnly | StyleState.MouseOver | StyleState.Selected: return (StyleType.ReadOnlySelectedMouseOver); default: return (StyleType.Default); } } #endregion #region GetEffectiveStyle /// /// GetEffectiveStyle /// /// /// public ColumnHeaderVisualStyle GetEffectiveStyle(GridColumn column) { StyleState styleState = GetStyleState(column, column.IsSelected); ColumnHeaderVisualStyle style = GetEffectiveStyle(column, styleState); return (style); } /// ///Gets the EffectiveStyle for the given StyleState /// /// /// /// public ColumnHeaderVisualStyle GetEffectiveStyle(GridColumn column, StyleState cellState) { StyleType type = GetStyleType(cellState); return (GetEffectiveStyle(column, type)); } internal ColumnHeaderVisualStyle GetEffectiveStyle(GridColumn column, StyleType type) { return (column.GetHeaderStyle(type)); } #endregion #region GetEffectiveRowHeaderStyle internal ColumnHeaderRowVisualStyle GetEffectiveRowHeaderStyle() { return (GetEffectiveRowHeaderStyleEx(GetRowHeaderState())); } internal ColumnHeaderRowVisualStyle GetEffectiveRowHeaderStyleEx(StyleState rowState) { ValidateRowHeaderStyle(); StyleType type = GetStyleType(rowState); return (GetRowHeaderStyle(type)); } #region ValidateRowHeaderStyle private void ValidateRowHeaderStyle() { if (_StyleUpdateCount != SuperGrid.StyleUpdateCount) { _EffectiveRowHeaderStyles = null; _StyleUpdateCount = SuperGrid.StyleUpdateCount; } } #endregion #region GetRowHeaderState private StyleState GetRowHeaderState() { StyleState rowState = StyleState.Default; if (_HitArea == HeaderArea.InRowHeader || _HitArea == HeaderArea.InWhitespace) rowState |= StyleState.MouseOver; GridPanel panel = GridPanel; if (panel != null) { if (panel.ReadOnly == true) rowState |= StyleState.ReadOnly; if (panel == SuperGrid.ActiveGrid) rowState |= StyleState.Selected; } return (rowState); } #endregion #region GetRowHeaderStyle private ColumnHeaderRowVisualStyle GetRowHeaderStyle(StyleType e) { if (_EffectiveRowHeaderStyles == null) _EffectiveRowHeaderStyles = new ColumnHeaderRowVisualStyles(); if (_EffectiveRowHeaderStyles.IsValid(e) == false) { ColumnHeaderRowVisualStyle style = new ColumnHeaderRowVisualStyle(); StyleType[] css = style.GetApplyStyleTypes(e); if (css != null) { foreach (StyleType cs in css) { style.ApplyStyle(SuperGrid.BaseVisualStyles.ColumnHeaderRowStyles[cs]); style.ApplyStyle(SuperGrid.DefaultVisualStyles.ColumnHeaderRowStyles[cs]); style.ApplyStyle(GridPanel.DefaultVisualStyles.ColumnHeaderRowStyles[cs]); } } SuperGrid.DoGetColumnHeaderRowHeaderStyleEvent(this, e, ref style); if (style.RowHeader.Background == null || style.RowHeader.Background.IsEmpty == true) style.RowHeader.Background = new Background(Color.WhiteSmoke); _EffectiveRowHeaderStyles[e] = style; } return (_EffectiveRowHeaderStyles[e]); } #endregion #endregion #endregion #endregion #region GetShowRootColumnHeaders private bool GetShowRootColumnHeaders(ColumnGroupHeader cgh) { while (cgh != null) { if (cgh.ShowColumnHeaders != Tbool.NotSet) return (cgh.ShowColumnHeaders == Tbool.True); cgh = cgh.Collection.Parent as ColumnGroupHeader; } return (_ShowGroupColumnHeaders); } #endregion #region GetAutoApplyGroupColor internal bool GetAutoApplyGroupColor(ColumnGroupHeader cgh) { if (cgh.AutoApplyGroupColors != Tbool.NotSet) return (cgh.AutoApplyGroupColors == Tbool.True); return (AutoApplyGroupColors); } #endregion #region IsGroupHeaderSelected /// ///Returns whether the given GroupHeader is selected (ie. all ///visible columns/headers it encompasses must be selected) /// ///GroupHeader ///true, if all selected public bool IsGroupHeaderSelected(ColumnGroupHeader cgh) { GridPanel panel = GridPanel; GridColumnCollection columns = panel.Columns; int[] map = columns.DisplayIndexMap; bool selected = false; for (int i = cgh.StartDisplayIndex; i <= cgh.EndDisplayIndex; i++) { if ((uint) i < map.Length) { GridColumn column = columns[map[i]]; if (column.Visible == true) { if (column.IsSelected == false) return (false); selected = true; } } } return (selected); } #endregion #region IsGroupHeaderReadOnly /// ///Returns whether the given GroupHeader is ReadOnly (ie. all ///visible columns/headers it encompasses must be ReadOnly) /// /// /// public bool IsGroupHeaderReadOnly(ColumnGroupHeader cgh) { GridPanel panel = GridPanel; GridColumnCollection columns = panel.Columns; int[] map = columns.DisplayIndexMap; bool readOnly = false; for (int i = cgh.StartDisplayIndex; i <= cgh.EndDisplayIndex; i++) { if ((uint)i >= map.Length) break; GridColumn column = columns[map[i]]; if (column.Visible == true) { if (column.IsReadOnly == false) return (false); readOnly = true; } } return (readOnly); } #endregion #region IsItemHFrozen internal bool IsItemHFrozen(object item) { if (item is GridColumn) return ((GridColumn)item).IsHFrozenEx; if (item is ColumnGroupHeader) return (IsGroupHeaderHFrozen(GridPanel, (ColumnGroupHeader)item)); return (false); } #endregion #region IsGroupHeaderHFrozen internal bool IsGroupHeaderHFrozen(GridPanel panel, ColumnGroupHeader cgh) { if (panel.IsSubPanel == false) { if (cgh != null) return (cgh.StartDisplayIndex < panel.FrozenColumnCount); } return (false); } #endregion #region GetBounds internal Rectangle GetBounds(GridPanel panel, GridColumn column) { Rectangle r = GetRelativeBounds(panel, column); return (GetScrollBounds(panel, column, r)); } #endregion #region GetRelativeBounds internal Rectangle GetRelativeBounds(GridPanel panel, GridColumn column) { Rectangle r = BoundsRelative; r.X = column.BoundsRelative.X; r.Width = column.BoundsRelative.Width; return (r); } #endregion #region GetScrollBounds internal Rectangle GetScrollBounds( GridPanel panel, GridColumn column, Rectangle r) { if (r.IsEmpty == false) { if (IsVFrozen == false) r.Y -= VScrollOffset; if (panel.IsSubPanel == true || column.IsHFrozen == false) r.X -= HScrollOffset; } return (r); } #endregion #region GetSubScrollBounds internal Rectangle GetSubScrollBounds(GridPanel panel, ColumnGroupHeader cgh) { Rectangle r = cgh.BoundsRelative; if (r.IsEmpty == false) { if (IsVFrozen == false) r.Y -= VScrollOffset; if (panel.IsSubPanel == true || IsGroupHeaderHFrozen(panel, cgh) == false) r.X -= HScrollOffset; } return (r); } #endregion #region GetSubContScrollBounds internal Rectangle GetSubContScrollBounds(GridPanel panel, ColumnGroupHeader cgh) { Rectangle r = cgh.BoundsRelative; r.Height = cgh.Size.Height; if (r.IsEmpty == false) { if (IsVFrozen == false) r.Y -= VScrollOffset; if (panel.IsSubPanel == true || IsGroupHeaderHFrozen(panel, cgh) == false) r.X -= HScrollOffset; } return (r); } #endregion #region GetContentBounds internal Rectangle GetContentBounds(GridPanel panel, ColumnHeaderVisualStyle style, Rectangle r) { if (_ShowHeaderImages == true) { object figure = style.GetFigure(panel); if (figure != null) { Size size = style.GetFigureSize(panel); if (style.IsOverlayImage != true) { switch (style.ImageAlignment) { case Alignment.TopCenter: r.Y += size.Height; r.Height -= size.Height; break; case Alignment.MiddleCenter: break; case Alignment.BottomCenter: r.Height -= size.Height; break; case Alignment.TopRight: case Alignment.MiddleRight: case Alignment.BottomRight: r.Width -= size.Width; break; default: r.X += size.Width; r.Width -= size.Width; break; } } } } return (r); } #endregion #region GetAdjustedBounds private Rectangle GetAdjustedBounds(VisualStyle style, Rectangle r) { r.X += Dpi.Width(style.BorderThickness.Left + style.Margin.Left + style.Padding.Left); r.Width -= Dpi.Width(style.BorderThickness.Horizontal + style.Margin.Horizontal + style.Padding.Horizontal); r.Y += Dpi.Height(style.BorderThickness.Top + style.Margin.Top + style.Padding.Top); r.Height -= Dpi.Height(style.BorderThickness.Vertical + style.Margin.Vertical + style.Padding.Vertical); return (r); } #endregion #region GetImageBounds /// /// Gets the bounding rectangle for the /// given column header image /// /// /// Bounding rectangle public Rectangle GetImageBounds(GridColumn column) { if (_ShowHeaderImages == true) { GridPanel panel = GridPanel; if (panel != null) { SuperGridControl sg = panel.SuperGrid; if (sg != null) { ColumnHeaderVisualStyle style = GetEffectiveStyle(column); object figure = style.GetFigure(panel); if (figure != null) { Rectangle bounds = GetBounds(panel, column); using (Graphics g = sg.CreateGraphics()) { Rectangle t = GetAdjustedBounds(style, GetContentBounds(panel, style, bounds)); return (style.GetFigureBounds(panel, t)); } } } } } return (Rectangle.Empty); } #endregion #region InvalidateHeader internal void InvalidateHeader(GridPanel panel, GridColumn column) { Rectangle bounds = BoundsRelative; if (panel.IsVFrozen == false) bounds.Y -= VScrollOffset; bounds.X = column.BoundsRelative.X; bounds.Width = column.BoundsRelative.Width; if (panel.IsSubPanel == true || column.IsHFrozen == false) bounds.X -= HScrollOffset; InvalidateRender(bounds); } private void InvalidateHeader(GridPanel panel, ColumnGroupHeader cgh) { Rectangle r = GetSubScrollBounds(panel, cgh); InvalidateRender(r); } #endregion #region InvalidateRowHeader internal void InvalidateRowHeader() { InvalidateRender(RowHeaderBounds); } #endregion #region InvalidateWhitespace internal void InvalidateWhitespace() { Rectangle bounds = Bounds; GridColumn col = GridPanel.Columns.LastVisibleColumn; if (col != null) { if (col.Bounds.Right < bounds.Right) { int n = bounds.Right - col.Bounds.Right; bounds.X = col.Bounds.Right; bounds.Width = n; } InvalidateRender(bounds); } } #endregion #region InvalidateItem private void InvalidateItem(GridPanel panel, object item) { if (item is GridColumn) InvalidateHeader(panel, (GridColumn)item); else if (item is ColumnGroupHeader) InvalidateHeader(panel, (ColumnGroupHeader)item); } #endregion #region CancelCapture /// /// Cancels any in progress operations (resize, reorder) /// that may have the mouse captured. /// public override void CancelCapture() { StopReorder(); StopResize(); _MouseDownHitItem = null; base.CancelCapture(); } #endregion } #region enums #region HeaderArea /// /// HeaderArea /// public enum HeaderArea { /// /// NoWhere /// NoWhere, /// /// InContent /// InContent, /// /// InResize /// InResize, /// /// InRowHeader /// InRowHeader, /// /// InRowHeaderResize /// InRowHeaderResize, /// /// InWhitespace /// InWhitespace, /// /// InMarkup /// InMarkup, /// /// InFilterMenu /// InFilterMenu, /// /// InGroupBox /// InGroupBox, } #endregion #region ImageVisibility /// /// ImageVisibility /// public enum ImageVisibility { /// /// NotSet /// NotSet = -1, /// /// Auto /// Auto, /// /// Always /// Always, /// /// Never /// Never, } #endregion #endregion }