mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-12-05 01:21:07 +01:00
ebb918296b
* CA-284226: Reduce unnecessary CanExecute() calls. * CA-284226: Optimize the performance of menu Migrate to Server and Start on Server. * Fix an error in updating Migrate menu with WLB, which lead to crash. * Clear the worker queue when menu is closed. Signed-off-by: Michael Zhao <michael.zhao@citrix.com> * Fix comments.
237 lines
7.0 KiB
C#
237 lines
7.0 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.Collections.Generic;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using XenAdmin.Core;
|
|
using System.Drawing;
|
|
|
|
|
|
/*
|
|
* This class provides the option of including an extra image on a menu item
|
|
* after the text.
|
|
* ToolStripMenuItems do not take their width from get preferred size, it is
|
|
* necessary to pad the text with blank characters so the second image can be
|
|
* drawn.
|
|
*
|
|
* Assumes all menu items are in the same menu for alignment.
|
|
*
|
|
*
|
|
*/
|
|
|
|
namespace XenAdmin.Controls
|
|
{
|
|
public class VisualMenuItem : ToolStripMenuItem
|
|
{
|
|
|
|
private static int leftMargin = 35;
|
|
private static int topMargin = 4;
|
|
private static int imagePadding = 5;
|
|
|
|
public override string Text
|
|
{
|
|
get
|
|
{
|
|
return base.Text;
|
|
}
|
|
set
|
|
{
|
|
base.Text = value;
|
|
UpdateWidths();
|
|
VisualMenuItemAlignData.Refresh();
|
|
RefreshPadding();
|
|
}
|
|
}
|
|
|
|
private double starRating = 0;
|
|
public double StarRating
|
|
{
|
|
get { return starRating; }
|
|
set { starRating = value; }
|
|
}
|
|
|
|
private int textWidth = 0;
|
|
public int TextWidth
|
|
{
|
|
get { return textWidth; }
|
|
}
|
|
|
|
private Image secondImage;
|
|
public Image SecondImage
|
|
{
|
|
get { return secondImage; }
|
|
set
|
|
{
|
|
secondImage = value;
|
|
VisualMenuItemAlignData.Refresh();
|
|
RefreshPadding();
|
|
this.Invalidate();
|
|
}
|
|
}
|
|
|
|
public VisualMenuItem()
|
|
{
|
|
}
|
|
|
|
public VisualMenuItem(string Text)
|
|
: base(Text)
|
|
{
|
|
// spacePadding will be set when text is assigned
|
|
}
|
|
|
|
public VisualMenuItem(string Text, Image Image)
|
|
: base(Text, Image)
|
|
{
|
|
// spacePadding will be set when text/image is assigned
|
|
}
|
|
|
|
private string spacePadding = "";
|
|
|
|
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
{
|
|
base.OnPaint(e);
|
|
if (secondImage == null)
|
|
return;
|
|
e.Graphics.DrawImage(secondImage,
|
|
leftMargin + VisualMenuItemAlignData.MaxStringLength + imagePadding,
|
|
topMargin, secondImage.Width, secondImage.Height);
|
|
|
|
}
|
|
|
|
protected override void OnParentChanged(ToolStrip oldParent, ToolStrip newParent)
|
|
{
|
|
base.OnParentChanged(oldParent, newParent);
|
|
if (HasAlignData())
|
|
{
|
|
VisualMenuItemAlignData.Refresh();
|
|
}
|
|
RefreshPadding();
|
|
}
|
|
|
|
private void UpdateWidths()
|
|
{
|
|
textWidth = Drawing.MeasureText(base.Text.TrimEnd(), this.Font).Width;
|
|
}
|
|
|
|
private bool HasAlignData()
|
|
{
|
|
// at the moment we just use a single static object, so no need to distinguish instance ownership
|
|
return true;
|
|
}
|
|
|
|
public void RefreshPadding()
|
|
{
|
|
spacePadding = "";
|
|
if (HasAlignData())
|
|
{
|
|
while (textWidth + Drawing.MeasureText(spacePadding, this.Font).Width < VisualMenuItemAlignData.MaxCombinedWidth)
|
|
{
|
|
spacePadding += " ";
|
|
}
|
|
}
|
|
base.Text = base.Text.TrimEnd();
|
|
base.Text += spacePadding;
|
|
}
|
|
|
|
public int ImageWidth()
|
|
{
|
|
if (secondImage == null)
|
|
{
|
|
return 0;
|
|
}
|
|
return (secondImage.Width + imagePadding * 2);
|
|
}
|
|
}
|
|
|
|
public static class VisualMenuItemAlignData
|
|
{
|
|
private static ToolStripMenuItem parentStrip;
|
|
public static ToolStripMenuItem ParentStrip
|
|
{
|
|
get { return parentStrip; }
|
|
set
|
|
{
|
|
parentStrip = value;
|
|
Refresh();
|
|
}
|
|
}
|
|
|
|
private static int maxStringLength;
|
|
public static int MaxStringLength
|
|
{
|
|
get { return maxStringLength; }
|
|
}
|
|
|
|
private static int maxCombinedWidth;
|
|
public static int MaxCombinedWidth
|
|
{
|
|
get { return maxCombinedWidth; }
|
|
}
|
|
|
|
private static Object locker = new Object();
|
|
|
|
public static void Refresh()
|
|
{
|
|
maxCombinedWidth = 0;
|
|
maxStringLength = 0;
|
|
if (parentStrip == null)
|
|
{
|
|
return;
|
|
}
|
|
lock (locker)
|
|
{
|
|
int maxImageWidth = 0;
|
|
foreach (ToolStripItem item in parentStrip.DropDownItems)
|
|
{
|
|
VisualMenuItem visItem;
|
|
if ((visItem = item as VisualMenuItem) != null)
|
|
{
|
|
int w = visItem.ImageWidth();
|
|
if (w > maxImageWidth)
|
|
{
|
|
maxImageWidth = w;
|
|
}
|
|
if (visItem.TextWidth > maxStringLength)
|
|
{
|
|
maxStringLength = visItem.TextWidth;
|
|
}
|
|
}
|
|
}
|
|
maxCombinedWidth = maxImageWidth + maxStringLength;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|