vbAccelerator - Contents of code file: acclExplorerBar_ExplorerBarItemWithText.cs

using System;
using System.Drawing;
using System.Drawing.Text;
using System.Windows.Forms;
using vbAccelerator.Components.Controls.ExplorerBarUtility;

namespace vbAccelerator.Components.Controls.ExplorerBarFramework
{
   /// <summary>
   /// An abstract class from which <see cref="ExplorerBarItem"/> objects
   /// that have text and an icon can be derived.  This class provides
   /// methods to maintain the text, icon index and
   /// formatting properties.  To allow any type of icon to be drawn,
   /// icon drawing and measurement is delegated to an object which implements
    the
   /// <see cref="IExplorerBarItemWithIcon"/> interface.  Concrete instances of
   /// this class should implement this interface.  The standard Explorer Bar 
   /// is provided with four concrete instances of this interface: Text, Link,
   /// Radio and Check.
   /// </summary>
   public abstract class ExplorerBarItemWithText : ExplorerBarItem
   {

      private int iconIndex = -1;
      private string text = "";
      private char mnemonicCode = '\0';
      private Font font = null;
      private bool bold = false;
      private Color hotForeColor = Color.Empty;
      private Color foreColor = Color.Empty;

      /// <summary>
      /// Constructs a new instance of this class
      /// </summary>
      public ExplorerBarItemWithText() : base()
      {
      }

      /// <summary>
      /// Determines whether this object should respond to the specified
       mnemonic
      /// key
      /// </summary>
      /// <param name="charCode">Mnemonic key character code</param>
      /// <returns><c>true</c> if should respond to the key, <c>false</c>
      /// otherwise.</returns>
      public override bool ContainsMnemonic(char charCode)
      {
         return (charCode == mnemonicCode);
      }

      /// <summary>
      /// Gets/sets the 0-based index of the icon to use for this icon, if any.
      /// If no icon is needed then the index should be set to -1.
      /// </summary>
      public int IconIndex
      {
         get
         {
            return iconIndex;
         }
         set
         {
            if (iconIndex != value)
            {
               iconIndex = value;
               OnAppearanceChanged();
            }
         }
      }

      /// <summary>
      /// Gets/sets the text to display for this item, if any.
      /// </summary>
      public string Text
      {
         get
         {
            return text;
         }
         set
         {
            if (!text.Equals(value))
            {
               text = value;
               DetermineMnemonicKey();
               OnSizeChanged();
            }
         }
      }

      /// <summary>
      /// Gets/sets the Font for this item.  This can be set to <c>null</c>
      /// to use the default font.
      /// </summary>
      public System.Drawing.Font Font
      {
         get
         {
            return font;
         }
         set
         {
            font = value;
            OnSizeChanged();
         }
      }

      /// <summary>
      /// Gets/sets whether the font for this item should be boldened.
      /// </summary>
      public bool Bold
      {
         get
         {
            return bold;
         }
         set
         {
            if (bold != value)
            {
               bold = value;
               OnSizeChanged();
            }
         }
      }

      /// <summary>
      /// Gets/sets the foreground colour for this item.  Use 
      /// <see cref="Color.Empty"/> for the default colour.
      /// </summary>
      public Color ForeColor
      {
         get
         {
            return foreColor;
         }
         set
         {
            if (foreColor != value)
            {
               foreColor = value;
               OnAppearanceChanged();
            }
         }
      }

      /// <summary>
      /// Gets/sets the hot foreground colour for this item.  Use 
      /// <see cref="Color.Empty"/> for the default colour.
      /// </summary>
      public Color ForeColorHot
      {
         get
         {
            return hotForeColor;
         }
         set
         {
            if (hotForeColor != value)
            {
               hotForeColor = value;
               OnAppearanceChanged();
            }
         }
      }

      private void DetermineMnemonicKey()
      {
         int pos = text.IndexOf("&");
         if ((pos > -1) && (pos < text.Length - 1))
         {
            mnemonicCode = text.Substring(pos + 1,
             1).ToLower().ToCharArray()[0];
         }
         else
         {
            mnemonicCode = '\0';
         }
      }

      /// <summary>
      /// Measures this item
      /// </summary>
      /// <param name="drawItemParams">Object specifying details needed to
       perform
      /// <param name="icon">Object which implements icon measurement and
       drawing</param>
      /// measurement.</param>
      protected virtual void DrawItem(
         IExplorerBarItemWithIcon icon,
         ExplorerBarDrawItemParams drawItemParams
         )
      {
         // Set up rectangle:
         Rectangle drawRect = new Rectangle(
            MarginSize * 2, 
            drawItemParams.Top, 
            (drawItemParams.ScrollShowing ? drawItemParams.WidthWithScroll :
             drawItemParams.WidthWithoutScroll) - MarginSize * 4,
            (drawItemParams.ScrollShowing ? HeightWithScroll :
             HeightWithoutScroll)
            );

         // Draw the icon
         int width = icon.DrawIcon(drawItemParams, drawRect);
         if (!drawItemParams.RightToLeft)
         {
            drawRect.X += (width + 2);
         }
         drawRect.Width -= (width + 2);

         // Draw the text:
         
         // Get the font
         System.Drawing.Font useFont = Font;
         bool disposeFont = false;
         if (useFont == null)
         {
            useFont = drawItemParams.DefaultFont;
         }
         FontStyle newFontStyle = useFont.Style;
         if (Bold)
         {
            newFontStyle |= FontStyle.Bold;
         }
         if (MouseOver && Clickable) 
         {
            newFontStyle |= FontStyle.Underline;
         }
         if (newFontStyle != useFont.Style)
         {
            useFont = new Font(useFont.FontFamily.Name, useFont.Size,
             newFontStyle);
            disposeFont = true;
         }

         StringFormat format = null;
         if (drawItemParams.RightToLeft)
         {
            format = new StringFormat(StringFormatFlags.DirectionRightToLeft);
         }
         else
         {
            format = new StringFormat();
         }
         //if (drawItemParams.ShowFocusCues)
         //{
            format.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show;
         //}
         //else
         //{
         //   format.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Hide;
         //}

         Color brushColor = ForeColor;
         if (MouseOver && Clickable)
         {
            brushColor = ForeColorHot;
         }
         if (brushColor == Color.Empty)
         {
            brushColor = ExplorerBarHelper.ItemTextColor(
               drawItemParams.Style, 
               Owner.XpTheme,
               Clickable,
               MouseOver);
         }
         Brush brush = new SolidBrush(brushColor);

         // Draw the text
         RectangleF textRect = new RectangleF(
            drawRect.Left, drawRect.Top, drawRect.Width, drawRect.Height);
         drawItemParams.Graphics.DrawString(
            Text, useFont, brush, textRect, format);

         brush.Dispose();

         if (Focused && Owner.ShowingFocusRectangle)
         {            
            SizeF textSize = drawItemParams.Graphics.MeasureString(
               Text, useFont, drawRect.Width, format);
            Rectangle focusRect = new Rectangle(drawRect.Location,
             textSize.ToSize());
            ControlPaint.DrawFocusRectangle(drawItemParams.Graphics,
             focusRect);            
         }

         format.Dispose();
         if (disposeFont)
         {
            useFont.Dispose();
         }
      }

      /// <summary>
      /// Measures this item
      /// </summary>
      /// <param name="icon">Object which implements icon measurement and
       drawing</param>
      /// <param name="measureItemParams">Object specifying details needed to
       perform
      /// measurement.</param>
      protected virtual void MeasureItem(
         IExplorerBarItemWithIcon icon,
         ExplorerBarMeasureItemParams measureItemParams
         )
      {
         int calcHeightWithScroll = 0;
         int calcHeightWithoutScroll = 0;
         int calcWidthWithScroll = 0;
         int calcWidthWithoutScroll = 0;

         // Set up measure width for the text:
         int measureWidth = measureItemParams.WidthWithoutScroll - MarginSize *
          4;

         // Evaluate the size of the icon:
         Size iconSize = icon.MeasureIcon(measureItemParams);
         calcHeightWithScroll = iconSize.Height;
         calcHeightWithoutScroll = calcHeightWithScroll;
         calcWidthWithScroll = iconSize.Width + 4;
         calcWidthWithoutScroll = iconSize.Width + 4;
         measureWidth -= iconSize.Width + 4;

         // Measure the size of the caption:
         
         // Get the font to use:
         Font useFont = Font;
         bool disposeFont = false;
         if (useFont == null)
         {
            useFont = measureItemParams.DefaultFont;
         }
         if (Bold)
         {
            if ((useFont.Style & FontStyle.Bold) != FontStyle.Bold)
            {
               useFont = new Font(useFont.FontFamily.Name, 
                  useFont.Size, useFont.Style | FontStyle.Bold);
               disposeFont = true;
            }
         }
         measureWidth -= 6;
         
         // Measure without scroll bar:
         SizeF size = measureItemParams.Graphics.MeasureString(
            Text, useFont, measureWidth);
         if (size.Height + 4 > calcHeightWithoutScroll)
         {
            calcHeightWithoutScroll = (int) size.Height + 4;
            calcHeightWithScroll = calcHeightWithoutScroll;                  
         }
         calcWidthWithoutScroll = (int) size.Width;

         // Measure with scroll bar
         measureWidth -= (measureItemParams.WidthWithoutScroll -
          measureItemParams.WidthWithScroll);
         size = measureItemParams.Graphics.MeasureString(
            Text, useFont, measureWidth);
         if (size.Height + 4 > calcHeightWithScroll)
         {
            calcHeightWithScroll = (int) size.Height + 4;
         }
         calcWidthWithScroll = (int) size.Width;

         if (disposeFont)
         {
            useFont.Dispose();
         }

         HeightWithScroll = calcHeightWithScroll;
         HeightWithoutScroll = calcHeightWithoutScroll;
         WidthWithScroll = calcWidthWithScroll;
         WidthWithoutScroll = calcWidthWithoutScroll;

      }

      /// <summary>
      /// Clones the fields associated with this object.  Used to supports the
      /// Clone method for concrete instances of the class.
      /// </summary>
      /// <param name="cloneTo">Object to clone fields to.</param>
      protected override void CloneFields(ExplorerBarItem cloneTo)
      {
         base.CloneFields(cloneTo);
         ExplorerBarItemWithText withText = (ExplorerBarItemWithText) cloneTo;
         withText.Bold = bold;
         withText.Font = font;
         withText.IconIndex = iconIndex;
         withText.Text = text;
         withText.ForeColor = foreColor;
         withText.ForeColorHot = hotForeColor;
      }

   }
}