mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-11-29 02:18:07 +01:00
abf4ae3f35
Signed-off-by: Konstantina Chremmou <konstantina.chremmou@citrix.com>
252 lines
9.2 KiB
C#
252 lines
9.2 KiB
C#
/* Copyright (c) Citrix Systems, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms,
|
|
* with or without modification, are permitted provided
|
|
* that the following conditions are met:
|
|
*
|
|
* * Redistributions of source code must retain the above
|
|
* copyright notice, this list of conditions and the
|
|
* following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the
|
|
* following disclaimer in the documentation and/or other
|
|
* materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
using System;
|
|
using System.Drawing;
|
|
using System.Windows.Forms;
|
|
|
|
namespace XenAdmin.Controls.CustomGridView
|
|
{
|
|
public class GridHeaderItem : GridStringItem
|
|
{
|
|
public const int ResizeGutter = 3; // the space between the columns within which we resize the columns rather than dragging them
|
|
|
|
private static readonly Image AscendingTriangle = Images.StaticImages.ascending_triangle;
|
|
private static readonly Image DescendingTriangle = Images.StaticImages.descending_triangle;
|
|
|
|
private static readonly Font SortFont = new Font(Program.DefaultFont.FontFamily, 7.0f);
|
|
private static readonly Pen LinePen = Pens.LightSteelBlue;
|
|
|
|
public readonly int MinimumWidth;
|
|
|
|
private readonly SortOrder defaultSortOrder;
|
|
public SortOrder Sort = SortOrder.None;
|
|
|
|
public int SortPriority = -1;
|
|
public bool IsDefaultSortColumn;
|
|
|
|
public bool GreyOut;
|
|
public bool Immovable;
|
|
public bool UnSizable;
|
|
|
|
private int width;
|
|
private String columnName;
|
|
|
|
public GridHeaderItem(HorizontalAlignment hAlign, VerticalAlignment vAlign, Brush foreBrush,
|
|
Font font, String text, SortOrder defaultSortOrder, int width, int minwidth, Brush hotbrush)
|
|
: base(text, hAlign, vAlign, false, false, foreBrush, font, hotbrush, font)
|
|
{
|
|
this.defaultSortOrder = defaultSortOrder;
|
|
this.width = width;
|
|
MinimumWidth = minwidth;
|
|
}
|
|
|
|
public String ColumnName
|
|
{
|
|
get
|
|
{
|
|
return columnName;
|
|
}
|
|
set
|
|
{
|
|
columnName = value;
|
|
}
|
|
}
|
|
|
|
public int Width
|
|
{
|
|
get
|
|
{
|
|
return width;
|
|
}
|
|
set
|
|
{
|
|
width = value;
|
|
}
|
|
}
|
|
|
|
public override void OnPaint(ItemPaintArgs itemPaintArgs)
|
|
{
|
|
if (!string.IsNullOrEmpty(sortdata.ToString()))
|
|
{
|
|
base.OnPaint(itemPaintArgs);
|
|
DrawGlyphs(itemPaintArgs);
|
|
}
|
|
}
|
|
|
|
public void DrawGlyphs(ItemPaintArgs itemPaintArgs)
|
|
{
|
|
Graphics g = itemPaintArgs.Graphics;
|
|
|
|
if (SortPriority > -1 && itemPaintArgs.Rectangle.Width - (AscendingTriangle.Width + 16) > 0)
|
|
{
|
|
// Draw the number showing the precedence of sorting in this column versus sorting in other columns
|
|
g.DrawString((SortPriority + 1).ToString(), SortFont, foreBrush, itemPaintArgs.Rectangle.Right - (AscendingTriangle.Width + 15), itemPaintArgs.Rectangle.Top + ((itemPaintArgs.Rectangle.Height / 2) - 7));
|
|
}
|
|
if (Sort != SortOrder.None && itemPaintArgs.Rectangle.Width - (AscendingTriangle.Width + 5) > 0)
|
|
{
|
|
// Draw the triangle showing ascending/descending sort order
|
|
DrawTriangle(g, Sort == SortOrder.Ascending ? AscendingTriangle : DescendingTriangle, itemPaintArgs);
|
|
}
|
|
|
|
DrawSideLine(g, itemPaintArgs, itemPaintArgs.Rectangle.Left - 1);
|
|
DrawSideLine(g, itemPaintArgs, itemPaintArgs.Rectangle.Right - 1);
|
|
}
|
|
|
|
private void DrawSideLine(Graphics g, ItemPaintArgs itemPaintArgs, int x)
|
|
{
|
|
g.DrawLine(LinePen, x, itemPaintArgs.Rectangle.Top, x, itemPaintArgs.Rectangle.Bottom - 1);
|
|
}
|
|
|
|
private void DrawTriangle(Graphics g, Image triangle, ItemPaintArgs itemPaintArgs)
|
|
{
|
|
g.DrawImageUnscaled(triangle, itemPaintArgs.Rectangle.Right - triangle.Width - 5, itemPaintArgs.Rectangle.Top + ((itemPaintArgs.Rectangle.Height - triangle.Height) / 2), triangle.Width, triangle.Height);
|
|
}
|
|
|
|
public override void OnEnter(Point p)
|
|
{
|
|
if (!Immovable && !string.IsNullOrEmpty(sortdata.ToString()))
|
|
{
|
|
Hot = true;
|
|
Row.GridView.Refresh();
|
|
}
|
|
}
|
|
|
|
public override void OnMouseMove(Point p)
|
|
{
|
|
if ((!UnSizable && (p.X >= CurrentRectangle.Width - ResizeGutter && p.X <= CurrentRectangle.Width)) || (!PreviousUnsizable() && (p.X < ResizeGutter && p.X >= 0)))
|
|
Row.Cursor = Cursors.SizeWE;
|
|
else
|
|
Row.Cursor = Cursors.Hand;
|
|
}
|
|
|
|
private bool PreviousUnsizable()
|
|
{
|
|
GridHeaderRow hr = (GridHeaderRow)Row;
|
|
int tindex = hr.Columns.IndexOf(ColumnName);
|
|
if (tindex <= 0)
|
|
return true;
|
|
string tother = hr.Columns[tindex - 1];
|
|
GridItemBase prevItem;
|
|
if (!hr.Items.TryGetValue(tother, out prevItem))
|
|
return true;
|
|
GridHeaderItem prevHeader = prevItem as GridHeaderItem;
|
|
if (prevHeader == null)
|
|
return true;
|
|
return prevHeader.UnSizable;
|
|
}
|
|
|
|
public override void OnLeave()
|
|
{
|
|
if (!string.IsNullOrEmpty(sortdata.ToString()))
|
|
{
|
|
Row.Cursor = Cursors.Default;
|
|
Hot = false;
|
|
Row.GridView.Refresh();
|
|
}
|
|
}
|
|
|
|
public override void OnClick(Point p)
|
|
{
|
|
if (!string.IsNullOrEmpty(sortdata.ToString()))
|
|
{
|
|
NextSort();
|
|
Row.GridView.Sort();
|
|
Row.GridView.Refresh();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Changes the sort order of this column to the next value
|
|
/// </summary>
|
|
private void NextSort()
|
|
{
|
|
switch (Sort)
|
|
{
|
|
case SortOrder.None:
|
|
SetSort(defaultSortOrder);
|
|
break;
|
|
case SortOrder.Ascending:
|
|
SetSort(defaultSortOrder == SortOrder.Ascending ? SortOrder.Descending : SortOrder.None);
|
|
break;
|
|
case SortOrder.Descending:
|
|
SetSort(defaultSortOrder == SortOrder.Ascending ? SortOrder.None : SortOrder.Ascending);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void SetSort(SortOrder sortOrder)
|
|
{
|
|
GridHeaderRow ghr = (GridHeaderRow)Row;
|
|
int oldPriority = SortPriority;
|
|
SortOrder oldSort = Sort;
|
|
|
|
Sort = sortOrder;
|
|
if (Sort == SortOrder.None) // removing sorting from this column
|
|
{
|
|
SortPriority = -1;
|
|
foreach (GridHeaderItem other in ghr.Items.Values)
|
|
{
|
|
if (other != this && other.SortPriority > oldPriority)
|
|
other.SortPriority--;
|
|
}
|
|
}
|
|
else if (oldSort == SortOrder.None) // starting to apply sorting to this column
|
|
{
|
|
SortPriority = 0;
|
|
foreach (GridHeaderItem other in ghr.Items.Values)
|
|
{
|
|
if (other != this && other.SortPriority > -1)
|
|
other.SortPriority++;
|
|
}
|
|
}
|
|
|
|
ghr.UpdateCompareOrder();
|
|
}
|
|
|
|
// When using this function, it is the caller's responsibility to
|
|
// make sure all the columns have a consistent set of priorities
|
|
internal void SetSort(int priority, SortOrder sortOrder)
|
|
{
|
|
SortPriority = priority;
|
|
Sort = sortOrder;
|
|
}
|
|
|
|
// When using this function, it is the caller's responsibility to
|
|
// make sure all the columns have a consistent set of priorities
|
|
internal void UnsetSort()
|
|
{
|
|
SortPriority = -1;
|
|
Sort = SortOrder.None;
|
|
}
|
|
}
|
|
}
|