Ignore:
Timestamp:
5/2/2009 8:35:52 AM (6 years ago)
Author:
lowjoel
Message:

-Recoded the Toolbar class to work like a standard MenuBar?. This allow for accelerators to work on the menus.
-The UxThemeAPI UpdateControlTheme? function also sets the themes on registered context menus and menu bars. This reduces the number of explicit calls.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eraser6/Eraser/ToolBar.cs

    r945 r966  
    2929using System.Runtime.InteropServices; 
    3030using System.Collections.ObjectModel; 
     31using Eraser.Util; 
    3132 
    3233namespace Eraser 
    3334{ 
    34     public partial class ToolBar : Control 
     35    public partial class ToolBar : System.Windows.Forms.MenuStrip 
    3536    { 
    3637        public ToolBar() 
     
    3839            //Create the base component 
    3940            InitializeComponent(); 
    40  
    41             //Initialize the toolbar item list 
    42             Items = new ToolBarItemCollection(this); 
    43  
    44             //Hook mouse move events to show the currently selected item 
    45             MouseMove += ToolBar_MouseMove; 
    46             MouseLeave += ToolBar_MouseLeave; 
    47             MouseClick += ToolBar_MouseClick; 
     41            Renderer = new EraserToolStripRenderer(); 
    4842        } 
    4943 
    50         void ToolBar_MouseMove(object sender, MouseEventArgs e) 
     44        private class EraserToolStripRenderer : UxThemeMenuRenderer 
    5145        { 
    52             Redraw(); 
    53         } 
     46            protected override void Initialize(ToolStrip toolStrip) 
     47            { 
     48                base.Initialize(toolStrip); 
     49                owner = toolStrip; 
     50            } 
    5451 
    55         void ToolBar_MouseLeave(object sender, EventArgs e) 
    56         { 
    57             Redraw(); 
    58         } 
     52            protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e) 
     53            { 
     54                if (e.ToolStrip == owner) 
     55                    //Draw the parent background image. This is not portable in that it will render 
     56                    //this code unreusable, but for the lack of anything better this will have to suffice! 
     57                    e.Graphics.DrawImage(Properties.Resources.BackgroundGradient, 
     58                        new Point(-owner.Left, -owner.Top)); 
     59                else 
     60                    base.OnRenderToolStripBackground(e); 
     61            } 
    5962 
    60         void ToolBar_MouseClick(object sender, MouseEventArgs e) 
    61         { 
    62             //See if the click was on any item's arrow. 
    63             Rectangle mouse_rect = new Rectangle(e.Location, new Size(1, 1)); 
    64             foreach (ToolBarItem i in Items) 
     63            protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e) 
    6564            { 
    66                 if (i.Menu != null && mouse_rect.IntersectsWith(i.MenuRect)) 
     65                if (e.ToolStrip != owner) 
     66                    base.OnRenderMenuItemBackground(e); 
     67            } 
     68 
     69            protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) 
     70            { 
     71                if (e.ToolStrip != owner) 
    6772                { 
    68                     //Show the menu below the toolbar item. 
    69                     Point mouse_point = PointToScreen(i.Rectangle.Location); 
    70                     i.Menu.Show(mouse_point.X, mouse_point.Y + i.Rectangle.Height); 
     73                    base.OnRenderItemText(e); 
     74                    return; 
    7175                } 
    72                 else if (mouse_rect.IntersectsWith(i.Rectangle)) 
     76 
     77                Graphics g = e.Graphics; 
     78 
     79                //Draw the actual text 
     80                Rectangle tempRect = e.TextRectangle; 
     81                tempRect.Inflate(3, 0); 
     82                tempRect.Offset(3, 0); 
     83                e.TextRectangle = tempRect; 
     84                using (SolidBrush textBrush = new SolidBrush(TextColour)) 
     85                    g.DrawString(e.Text, e.TextFont, textBrush, e.TextRectangle); 
     86 
     87                //If the text has got a selection, draw an underline 
     88                if (e.Item.Selected) 
    7389                { 
    74                     //Broadcast the item click event 
    75                     i.OnToolbarItemClicked(this); 
     90                    SizeF textSize = g.MeasureString(e.Text, e.TextFont); 
     91                    using (Pen underlinePen = new Pen(TextColour)) 
     92                    { 
     93                        Point underlineStart = e.TextRectangle.Location; 
     94                        underlineStart.Offset(0, Point.Truncate(textSize.ToPointF()).Y); 
     95                        Point underlineEnd = underlineStart; 
     96                        underlineEnd.Offset(e.TextRectangle.Width, 0); 
     97 
     98                        g.DrawLine(underlinePen, underlineStart, underlineEnd); 
     99                    } 
    76100                } 
    77101            } 
    78         } 
    79          
    80         /// <summary> 
    81         /// Draws the Tool Bar on the given graphics object. 
    82         /// </summary> 
    83         /// <param name="dc">Graphics object to draw on.</param> 
    84         public void Draw(Graphics rawDC) 
    85         { 
    86             //Create a backing bitmap buffer to prevent flicker 
    87             Bitmap back_bmp = new Bitmap(Width, Height); 
    88             Graphics dc = Graphics.FromImage(back_bmp); 
    89102 
    90             //Draw the parent background image. This is not portable in that it will render 
    91             //this code unreusable, but for the lack of anything better this will have to suffice! 
    92             dc.DrawImage(Properties.Resources.BackgroundGradient, new Point(-Left, -Top)); 
    93              
    94             Point mouse_pos = PointToClient(MousePosition); 
    95             int x = 0; 
     103            /// <summary> 
     104            /// The margin between a drop-down arrow and the surrounding items. 
     105            /// </summary> 
     106            private const int ArrowMargin = 0; 
    96107 
    97             foreach (ToolBarItem i in Items) 
    98             { 
    99                 { 
    100                     Point pos = i.Rectangle.Location; 
    101                     pos.X = x; 
    102                     pos.Y = 0; 
    103                     i.Rectangle.Location = pos; 
    104                 } 
     108            /// <summary> 
     109            /// The colour of the menu bar text. 
     110            /// </summary> 
     111            private readonly Color TextColour = Color.White; 
    105112 
    106                 if (i.Bitmap != null) 
    107                 { 
    108                     i.BitmapRect = new Rectangle(x, 0, i.Bitmap.Width, i.Bitmap.Height); 
    109                     dc.DrawImage(i.Bitmap, i.BitmapRect); 
    110  
    111                     x += i.BitmapRect.Width + 4; 
    112                 } 
    113  
    114                 //Draw the toolbar item text 
    115                 SizeF string_size = dc.MeasureString(i.Text, Font); 
    116                 i.TextRect = new Rectangle(x, (int)(Height - string_size.Height) / 2, 
    117                     (int)string_size.Width, (int)string_size.Height); 
    118                 dc.DrawString(i.Text, Font, Brushes.White, i.TextRect.Location); 
    119                 x += i.TextRect.Width; 
    120                  
    121                 //If there is a menu associated draw a drop-down glyph 
    122                 if (i.Menu != null) 
    123                 { 
    124                     Bitmap menu_arrow = Properties.Resources.ToolbarArrow; 
    125                     i.MenuRect = new Rectangle(x += 6, i.TextRect.Y, 
    126                         menu_arrow.Width, menu_arrow.Height); 
    127                     dc.DrawImage(menu_arrow, i.MenuRect); 
    128                     x += i.MenuRect.Width; 
    129                 } 
    130  
    131                 //Update the size of the item rectangle 
    132                 { 
    133                     Size size = i.Rectangle.Size; 
    134                     size.Width = x - i.Rectangle.Location.X; 
    135                     size.Height = Height; 
    136                     i.Rectangle.Size = size; 
    137                 } 
    138  
    139                 //If the mouse cursor intersects with the item then draw an underline. 
    140                 if (i.Rectangle.IntersectsWith(new Rectangle(mouse_pos, new Size(1, 1)))) 
    141                     dc.DrawLine(Pens.White, new Point(i.TextRect.Left, i.TextRect.Bottom + 1), 
    142                         new Point(i.TextRect.Right, i.TextRect.Bottom + 1)); 
    143  
    144                 //Padding between items. 
    145                 x += 16; 
    146             } 
    147  
    148             rawDC.DrawImage(back_bmp, new Point(0, 0)); 
    149         } 
    150  
    151         /// <summary> 
    152         /// Redraws the Tool Bar by creating a Graphics object. 
    153         /// </summary> 
    154         public void Redraw() 
    155         { 
    156             Draw(CreateGraphics()); 
    157         } 
    158  
    159         /// <summary> 
    160         /// Paints the control. 
    161         /// </summary> 
    162         /// <param name="pe">Paint event object.</param> 
    163         protected override void OnPaint(PaintEventArgs e) 
    164         { 
    165             Draw(e.Graphics); 
    166  
    167             // Calling the base class OnPaint 
    168             base.OnPaint(e); 
    169         } 
    170  
    171         /// <summary> 
    172         /// Stores the items in the Tool Bar. 
    173         /// </summary> 
    174         public ToolBarItemCollection Items 
    175         { 
    176             get; 
    177             private set; 
     113            private ToolStrip owner; 
    178114        } 
    179115    } 
    180  
    181     public class ToolBarItem 
    182     { 
    183         /// <summary> 
    184         /// Tool bar item text. 
    185         /// </summary> 
    186         [Description("Toolbar item text")] 
    187         public string Text 
    188         { 
    189             get { return text; } 
    190             set 
    191             { 
    192                 text = value; 
    193                 if (Window != null) 
    194                     Window.Redraw(); 
    195             } 
    196         } 
    197  
    198         /// <summary> 
    199         /// Item bitmap. 
    200         /// </summary> 
    201         [Description("Item Bitmap")] 
    202         public Bitmap Bitmap 
    203         { 
    204             get { return bitmap; } 
    205             set 
    206             { 
    207                 bitmap = value; 
    208                 if (Window != null) 
    209                     Window.Redraw(); 
    210             } 
    211         } 
    212  
    213         /// <summary> 
    214         /// Item drop-down menu 
    215         /// </summary> 
    216         public ContextMenuStrip Menu 
    217         { 
    218             get { return menu; } 
    219             set 
    220             { 
    221                 menu = value; 
    222                 if (Window != null) 
    223                     Window.Redraw(); 
    224             } 
    225         } 
    226  
    227         /// <summary> 
    228         /// Item click event handler 
    229         /// </summary> 
    230         public EventHandler<EventArgs> ToolBarItemClicked 
    231         { 
    232             get; 
    233             set; 
    234         } 
    235  
    236         internal void OnToolbarItemClicked(object sender) 
    237         { 
    238             if (ToolBarItemClicked != null) 
    239                 ToolBarItemClicked(sender, new EventArgs()); 
    240         } 
    241  
    242         private string text; 
    243         private Bitmap bitmap; 
    244         private ContextMenuStrip menu; 
    245  
    246         /// <summary> 
    247         /// The owning window of this item. 
    248         /// </summary> 
    249         internal ToolBar Window; 
    250  
    251         /// <summary> 
    252         /// Stores the rectangle of this item. 
    253         /// </summary> 
    254         internal Rectangle Rectangle; 
    255  
    256         /// <summary> 
    257         /// Stores the rectangle of the bitmap. 
    258         /// </summary> 
    259         internal Rectangle BitmapRect; 
    260  
    261         /// <summary> 
    262         /// Stores the rectangle of the text. 
    263         /// </summary> 
    264         internal Rectangle TextRect; 
    265  
    266         /// <summary> 
    267         /// Stores the rectangle of the drop-down arrow. 
    268         /// </summary> 
    269         internal Rectangle MenuRect; 
    270     } 
    271  
    272     public class ToolBarItemCollection : ICollection<ToolBarItem>, IList<ToolBarItem>, 
    273         IEnumerable<ToolBarItem> 
    274     { 
    275         /// <summary> 
    276         /// Constructor. 
    277         /// </summary> 
    278         /// <param name="win">The owning toolbar window.</param> 
    279         internal ToolBarItemCollection(ToolBar win) 
    280         { 
    281             window = win; 
    282         } 
    283  
    284         #region ICollection<ToolBarItem> Members 
    285         public void Add(ToolBarItem item) 
    286         { 
    287             Insert(Count, item); 
    288         } 
    289  
    290         public void Clear() 
    291         { 
    292             foreach (ToolBarItem item in list) 
    293                 item.Window = null; 
    294             list.Clear(); 
    295             window.Redraw(); 
    296         } 
    297  
    298         public bool Contains(ToolBarItem item) 
    299         { 
    300             return list.Contains(item); 
    301         } 
    302  
    303         public void CopyTo(ToolBarItem[] array, int arrayIndex) 
    304         { 
    305             list.CopyTo(array, arrayIndex); 
    306         } 
    307  
    308         public int Count 
    309         { 
    310             get { return list.Count; } 
    311         } 
    312  
    313         public bool IsReadOnly 
    314         { 
    315             get { return false; } 
    316         } 
    317  
    318         public bool Remove(ToolBarItem item) 
    319         { 
    320             int index = IndexOf(item); 
    321             if (index < 0) 
    322                 return false; 
    323  
    324             RemoveAt(index); 
    325             return true; 
    326         } 
    327         #endregion 
    328  
    329         #region IEnumerable<ToolBarItem> Members 
    330         public IEnumerator<ToolBarItem> GetEnumerator() 
    331         { 
    332             return list.GetEnumerator(); 
    333         } 
    334         #endregion 
    335  
    336         #region IEnumerable Members 
    337         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    338         { 
    339             return list.GetEnumerator(); 
    340         } 
    341         #endregion 
    342  
    343         #region IList<ToolBarItem> Members 
    344         public int IndexOf(ToolBarItem item) 
    345         { 
    346             return list.IndexOf(item); 
    347         } 
    348  
    349         public void Insert(int index, ToolBarItem item) 
    350         { 
    351             if (item.Window != null) 
    352                 throw new ArgumentException("The item being added already is owned by " + 
    353                     "another ToolBar control. Remove the item from the other control " + 
    354                     "before inserting it into this one."); 
    355  
    356             item.Window = window; 
    357             list.Insert(index, item); 
    358             window.Redraw(); 
    359         } 
    360  
    361         public void RemoveAt(int index) 
    362         { 
    363             ToolBarItem item = list[index]; 
    364             item.Window = null; 
    365             list.RemoveAt(index); 
    366             window.Redraw(); 
    367         } 
    368  
    369         public ToolBarItem this[int index] 
    370         { 
    371             get 
    372             { 
    373                 return list[index]; 
    374             } 
    375             set 
    376             { 
    377                 list[index] = value; 
    378                 if (window != null) 
    379                     window.Redraw(); 
    380             } 
    381         } 
    382         #endregion 
    383  
    384         /// <summary> 
    385         /// The window owning the items in this list. 
    386         /// </summary> 
    387         private ToolBar window; 
    388  
    389         /// <summary> 
    390         /// The list storing the toolbar items. 
    391         /// </summary> 
    392         private List<ToolBarItem> list = new List<ToolBarItem>(); 
    393     } 
    394116} 
Note: See TracChangeset for help on using the changeset viewer.