mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-12-23 00:46:03 +01:00
7c0bc50b4a
Inc. Signed-off-by: Gabor Apati-Nagy<gabor.apati-nagy@citrix.com>
216 lines
8.3 KiB
C#
216 lines
8.3 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.ComponentModel;
|
|
using System.Drawing;
|
|
using System.Data;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using System.Drawing.Drawing2D;
|
|
using XenAdmin.Controls;
|
|
|
|
namespace XenAdmin.Wizards
|
|
{
|
|
public partial class WizardProgress : UserControl
|
|
{
|
|
private static readonly Color HighlightColorMiddle = Color.FromArgb(10, 80, 200);
|
|
private static readonly Color HighlightColorEdge = Color.FromArgb(9, 70, 162);
|
|
private static readonly Color bgBrushColor = Color.FromArgb(255, 255, 255);
|
|
|
|
private int _currentStep = 0;
|
|
|
|
public WizardProgress()
|
|
{
|
|
InitializeComponent();
|
|
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
|
|
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
|
SetStyle(ControlStyles.UserPaint, true);
|
|
SetStyle(ControlStyles.ResizeRedraw, true);
|
|
}
|
|
|
|
public readonly List<XenTabPage> Steps = new List<XenTabPage>();
|
|
|
|
/// <summary>
|
|
/// Transitions to the previous non-disabled step, or remains at the present step
|
|
/// if already at the first non-disabled step.
|
|
/// </summary>
|
|
public void PreviousStep()
|
|
{
|
|
System.Diagnostics.Trace.Assert(!IsFirstStep);
|
|
|
|
if (!OnLeavingStep(false))
|
|
{
|
|
// If anyone cancels the transition, remain on this step
|
|
return;
|
|
}
|
|
|
|
int destination = _currentStep - 1;
|
|
// Find the previous non-disabled step
|
|
while (destination > 0 && Steps[destination].DisableStep)
|
|
{
|
|
destination--;
|
|
}
|
|
if (!Steps[destination].DisableStep)
|
|
{
|
|
_currentStep = destination;
|
|
Invalidate();
|
|
OnEnteringStep(false);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Transitions to the next non-disabled step, or remains at the present step
|
|
/// if already at the last non-disabled step.
|
|
/// </summary>
|
|
public void NextStep()
|
|
{
|
|
if (!OnLeavingStep(true))
|
|
{
|
|
// If anyone cancels the transition, remain on this step
|
|
return;
|
|
}
|
|
|
|
System.Diagnostics.Trace.Assert(!IsLastStep);
|
|
|
|
int destination = _currentStep + 1;
|
|
// Find the next non-disabled step
|
|
while (destination < Steps.Count - 1 && Steps[destination].DisableStep)
|
|
{
|
|
destination++;
|
|
}
|
|
if (!Steps[destination].DisableStep)
|
|
{
|
|
_currentStep = destination;
|
|
Invalidate();
|
|
OnEnteringStep(true);
|
|
}
|
|
}
|
|
|
|
public event EventHandler<WizardProgressEventArgs> LeavingStep;
|
|
public event EventHandler<WizardProgressEventArgs> EnteringStep;
|
|
|
|
public XenTabPage CurrentStepTabPage
|
|
{
|
|
get { return Steps[_currentStep]; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// IsFirstStep doesn't include any disabled pages at the beginning,
|
|
/// because we can never turn these on (within this instance of the wizard).
|
|
/// </summary>
|
|
public bool IsFirstStep
|
|
{
|
|
get
|
|
{
|
|
int firstRealStep = 0;
|
|
while (firstRealStep < Steps.Count && Steps[firstRealStep].DisableStep)
|
|
++firstRealStep;
|
|
return _currentStep == firstRealStep;
|
|
}
|
|
}
|
|
|
|
public bool IsLastStep
|
|
{
|
|
get { return _currentStep == Steps.Count - 1; }
|
|
}
|
|
|
|
/// <returns>
|
|
/// True if the event has gone through, false if cancelled.
|
|
/// </returns>
|
|
private bool OnLeavingStep(bool isForwardsTransition)
|
|
{
|
|
WizardProgressEventArgs e = new WizardProgressEventArgs(isForwardsTransition);
|
|
if (LeavingStep != null)
|
|
LeavingStep(this, e);
|
|
return !e.Cancelled;
|
|
}
|
|
|
|
private void OnEnteringStep(bool isForwardsTransition)
|
|
{
|
|
WizardProgressEventArgs e = new WizardProgressEventArgs(isForwardsTransition);
|
|
if (EnteringStep != null)
|
|
EnteringStep(this, e);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Draws the list of wizard steps, with the current step highlighted and any disabled steps grayed out.
|
|
/// </summary>
|
|
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
{
|
|
Bitmap bg = Properties.Resources.wizard_background;
|
|
int bg_h = (int)(bg.Height * (Width / (float)bg.Width)); //The assumption made is that Width/bg.Width ratio always matches the system's dpi setting. Normally (at 100% dpi setting) this equals to 1.
|
|
int bg_top = Height - bg_h;
|
|
if (bg_top > 0)
|
|
{
|
|
using (SolidBrush bgBrush = new SolidBrush(bgBrushColor))
|
|
e.Graphics.FillRectangle(bgBrush, new Rectangle(0, 0, Width, bg_top));
|
|
}
|
|
|
|
int bg_w = Width;
|
|
|
|
//This makes sure we compensate for rounding if it happened while bg_h was calculated. (to avoid gap on the right)
|
|
//Switch to 125% dpi to see why this is needed...
|
|
if (Width / (float)bg.Width != 1f)
|
|
bg_w++;
|
|
|
|
e.Graphics.DrawImage(bg, new Rectangle(0, bg_top, bg_w, bg_h ));
|
|
|
|
using (LinearGradientBrush highlight = new LinearGradientBrush(Point.Empty, new Point(Width, 0), HighlightColorEdge, HighlightColorMiddle))
|
|
{
|
|
highlight.SetBlendTriangularShape(0.5f);
|
|
float y = 15F;
|
|
for (int step = 0; step < Steps.Count; step++)
|
|
{
|
|
if (step == _currentStep)
|
|
{
|
|
e.Graphics.FillRectangle(highlight, 0, y, Width, 20F);
|
|
TextRenderer.DrawText(e.Graphics, Steps[step].Text, Program.DefaultFontBold, new Rectangle(10, (int)y, Width, 20), SystemColors.HighlightText,
|
|
TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.HidePrefix);
|
|
}
|
|
else
|
|
{
|
|
TextRenderer.DrawText(e.Graphics, Steps[step].Text, Program.DefaultFont, new Rectangle(10, (int)y, Width, 20), Steps[step].DisableStep ? SystemColors.GrayText : Color.Black, TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.HidePrefix);
|
|
}
|
|
y += 24F;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void OnPaintBackground(PaintEventArgs e)
|
|
{
|
|
//base.OnPaintBackground(e);
|
|
}
|
|
}
|
|
}
|