xenadmin/XenAdmin/Controls/CustomGridView/GridStringItem.cs

253 lines
10 KiB
C#
Raw Normal View History

/* 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;
using XenCenterLib;
using XenAdmin.Core;
namespace XenAdmin.Controls.CustomGridView
{
public class GridStringItem : GridItemBase
{
protected readonly HorizontalAlignment hAlign = HorizontalAlignment.Left;
protected readonly VerticalAlignment vAlign = VerticalAlignment.Top;
protected readonly Font font, hotFont;
protected readonly Brush foreBrush, hotBrush;
public Object sortdata;
private readonly Object data;
protected readonly bool respondToSelect;
protected bool hot = false;
public GridStringItem(object data, HorizontalAlignment hAlign, VerticalAlignment vAlign, bool respondToSelect,
bool clickSelectsRow, Brush foreBrush, Font font, Brush hotBrush, Font hotFont)
: this(data, hAlign, vAlign, respondToSelect, clickSelectsRow, foreBrush, font, hotBrush, hotFont, 1, null, null)
{
}
public GridStringItem(object data, HorizontalAlignment hAlign, VerticalAlignment vAlign, bool respondToSelect,
bool clickSelectsRow, Brush foreBrush, Font font)
: this(data, hAlign, vAlign, respondToSelect, clickSelectsRow, foreBrush, font, foreBrush, font, 1, null, null)
{
}
public GridStringItem(object data, HorizontalAlignment hAlign, VerticalAlignment vAlign, bool respondToSelect,
bool clickSelectsRow, Brush foreBrush, Font font, EventHandler onClickDelegate)
: this(data, hAlign, vAlign, respondToSelect, clickSelectsRow, foreBrush, font, foreBrush, font, 1, onClickDelegate, null)
{
}
public GridStringItem(object data, HorizontalAlignment hAlign, VerticalAlignment vAlign, bool respondToSelect,
bool clickSelectsRow, Brush foreBrush, Font font, int rowspan)
: this(data, hAlign, vAlign, respondToSelect, clickSelectsRow, foreBrush, font, foreBrush, font, rowspan, null, null)
{
}
public GridStringItem(object data, HorizontalAlignment hAlign, VerticalAlignment vAlign, bool respondToSelect,
bool clickSelectsRow, Brush foreBrush, Font font, int rowspan, EventHandler onClickDelegate)
: this(data, hAlign, vAlign, respondToSelect, clickSelectsRow, foreBrush, font, foreBrush, font, rowspan, onClickDelegate, null)
{
}
public GridStringItem(object data, HorizontalAlignment hAlign, VerticalAlignment vAlign, bool respondToSelect,
bool clickSelectsRow, Brush foreBrush, Font font, Brush hotBrush, Font hotFont, EventHandler onClickDelegate, EventHandler onRightClickDelegate)
: this(data, hAlign, vAlign, respondToSelect, clickSelectsRow, foreBrush, font, hotBrush, hotFont, 1, onClickDelegate, onRightClickDelegate)
{
}
// We use the convention that the click delegate is for single-click or double-click depending whether single-click already selects the row
public GridStringItem(object data, HorizontalAlignment hAlign, VerticalAlignment vAlign, bool respondToSelect,
bool clickSelectsRow, Brush foreBrush, Font font, Brush hotBrush, Font hotFont, int rowSpan, EventHandler onClickDelegate, EventHandler onRightClickDelegate)
: base(data == null, rowSpan, clickSelectsRow, clickSelectsRow ? null : onClickDelegate, clickSelectsRow ? onClickDelegate: null, onRightClickDelegate)
{
this.data = data;
this.sortdata = data;
this.hAlign = hAlign;
this.vAlign = vAlign;
this.respondToSelect = respondToSelect;
this.foreBrush = foreBrush;
this.font = font;
this.hotBrush = hotBrush;
this.hotFont = hotFont;
}
public virtual bool Hot
{
get { return hot; }
set { hot = value; }
}
public override void OnPaint(ItemPaintArgs itemPaintArgs)
{
OnPaintInternal(itemPaintArgs,
Hot ? hotFont : font,
Hot ? hotBrush : foreBrush);
}
protected virtual void OnPaintInternal(ItemPaintArgs itemPaintArgs, Font localFont, Brush localForeBrush)
{
if (data == null)
return;
string output = (data is DateTime ? HelpersGUI.DateTimeToString((DateTime)data, Messages.DATEFORMAT_DMY_HM, true) : data.ToString()); // exception for DateTime: CA-46983
// Replace either form of line ending with a space
output = output.Replace("\n", " ").Replace("\r", "");
Point loc = new Point();
string text = Ellipsise(itemPaintArgs.Graphics, output, itemPaintArgs.Rectangle, localFont, out loc);
if (!string.IsNullOrEmpty(text))
{
// Change text and background colour for selected rows
bool selected = (respondToSelect && (itemPaintArgs.State & ItemState.Selected) > 0);
if (selected)
{
Size textSize = Drawing.MeasureText(text, localFont);
Rectangle textRect;
textRect = new Rectangle(loc, textSize);
itemPaintArgs.Graphics.FillRectangle(new SolidBrush(SystemColors.Highlight), textRect);
localForeBrush = new SolidBrush(SystemColors.HighlightText);
}
itemPaintArgs.Graphics.DrawString(text, localFont, localForeBrush, loc);
}
}
private bool IsOverText(Point point)
{
Rectangle rect = new Rectangle();
if (hAlign == HorizontalAlignment.Center)
rect.X = (CurrentRectangle.Width / 2) - (int)(DataSize.Width / 2);
if (vAlign == VerticalAlignment.Middle)
rect.Y = (CurrentRectangle.Height / 2) - (int)(DataSize.Height / 2);
rect.Width = (int)DataSize.Width;
rect.Height = (int)DataSize.Height;
return rect.Contains(point);
}
public override void OnMouseDown(Point point)
{
if (IsOverText(point))
base.OnMouseDown(point);
}
public override void OnClick(Point point)
{
if (!IsOverText(point))
Row.GridView.UnselectAllRows();
else
base.OnClick(point);
}
public override void OnDoubleClick(Point point)
{
if (IsOverText(point))
base.OnDoubleClick(point);
}
public override void OnStartDrag(Point point)
{
if (IsOverText(point))
base.OnStartDrag(point);
}
internal SizeF DataSize;
internal Rectangle CurrentRectangle;
/// <summary>
/// Gets the total width of all the contents of the grid item.
/// </summary>
/// <param name="column">The column this item belongs to</param>
internal override int GetGridItemWidth(string column)
{
if (Row.ItemColumnSpan(this, column) == 1)
return (int)Math.Ceiling((double)DataSize.Width);
return base.GetGridItemWidth(column);
}
private string Ellipsise(Graphics g, String text, Rectangle rectangle, Font font, out Point loc)
{
DataSize = g.MeasureString(text, font);
CurrentRectangle = rectangle;
int width = (int)DataSize.Width;
if (hAlign == HorizontalAlignment.Center && width < rectangle.Width)
loc = new Point(rectangle.Left + (rectangle.Width - width) / 2, rectangle.Top);
else
loc = rectangle.Location;
if (vAlign == VerticalAlignment.Middle)
loc.Y += (int)((rectangle.Height - DataSize.Height) / 2);
return text.Ellipsise(rectangle, font);
}
public override void OnMouseMove(Point point)
{
System.Diagnostics.Trace.Assert(Row != null);
if (onClickDelegate != null && IsOverText(point))
{
Row.Cursor = Cursors.Hand;
Hot = true;
}
else
{
Row.Cursor = Cursors.Default;
Hot = false;
}
Row.GridView.Refresh();
}
public override void OnLeave()
{
Row.Cursor = Cursors.Default;
Hot = false;
Row.GridView.Refresh();
}
public override int CompareTo(GridItemBase gridItem)
{
GridStringItem other = gridItem as GridStringItem;
Object otherdata = other == null ? null : other.sortdata;
if (sortdata == null)
return otherdata == null ? 0 : 1;
if (otherdata == null)
return -1;
return StringUtility.NaturalCompare(sortdata.ToString(), other.sortdata.ToString());
}
}
}