/* * $Id$ * Copyright 2008 The Eraser Project * Original Author: Joel Low * Modified By: * * This file is part of Eraser. * * Eraser is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * Eraser is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * A copy of the GNU General Public License can be found at * . */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace Eraser { public partial class ToolBar : Control { public ToolBar() { //Create the base component InitializeComponent(); //Initialize the toolbar item list items = new List(); //Hook mouse move events to show the currently selected item MouseMove += new MouseEventHandler(ToolBar_MouseMove); MouseLeave += new EventHandler(ToolBar_MouseLeave); MouseClick += new MouseEventHandler(ToolBar_MouseClick); } void ToolBar_MouseMove(object sender, MouseEventArgs e) { Redraw(); } void ToolBar_MouseLeave(object sender, EventArgs e) { Redraw(); } void ToolBar_MouseClick(object sender, MouseEventArgs e) { //See if the click was on any item's arrow. Rectangle mouse_rect = new Rectangle(e.Location, new Size(1, 1)); foreach (ToolBarItem i in items) { if (i.Menu != null && mouse_rect.IntersectsWith(i.MenuRect)) { //Show the menu below the toolbar item. Point mouse_point = PointToScreen(i.Rectangle.Location); i.Menu.Show(mouse_point.X, mouse_point.Y + i.Rectangle.Height); } else if (mouse_rect.IntersectsWith(i.Rectangle)) { //Broadcast the item click event i.OnToolbarItemClicked(this); } } } /// /// Draws the Tool Bar on the given graphics object. /// /// Graphics object to draw on. public void Draw(Graphics sdc) { //Create a backing bitmap buffer to prevent flicker Bitmap back_bmp = new Bitmap(Width, Height); Graphics dc = Graphics.FromImage(back_bmp); //Draw the parent background image. This is not portable in that it will render //this code unreusable, but for the lack of anything better this will have to suffice! dc.DrawImage(Properties.Resources.BackgroundGradient, new Point(-Left, -Top)); Point mouse_pos = PointToClient(MousePosition); int x = 0; foreach (ToolBarItem i in items) { { Point pos = i.Rectangle.Location; pos.X = x; pos.Y = 0; i.Rectangle.Location = pos; } if (i.Bitmap != null) { i.BitmapRect = new Rectangle(x, 0, i.Bitmap.Width, i.Bitmap.Height); dc.DrawImage(i.Bitmap, i.BitmapRect); x += i.BitmapRect.Width + 4; } //Draw the toolbar item text SizeF string_size = dc.MeasureString(i.Text, Font); i.TextRect = new Rectangle(x, (int)(Height - string_size.Height) / 2, (int)string_size.Width, (int)string_size.Height); dc.DrawString(i.Text, Font, Brushes.White, i.TextRect.Location); x += i.TextRect.Width; //If there is a menu associated draw a drop-down glyph if (i.Menu != null) { Bitmap menu_arrow = Properties.Resources.ToolbarArrow; i.MenuRect = new Rectangle(x += 6, i.TextRect.Y, menu_arrow.Width, menu_arrow.Height); dc.DrawImage(menu_arrow, i.MenuRect); x += i.MenuRect.Width; } //Update the size of the item rectangle { Size size = i.Rectangle.Size; size.Width = x - i.Rectangle.Location.X; size.Height = Height; i.Rectangle.Size = size; } //If the mouse cursor intersects with the item then draw an underline. if (i.Rectangle.IntersectsWith(new Rectangle(mouse_pos, new Size(1, 1)))) dc.DrawLine(Pens.White, new Point(i.TextRect.Left, i.TextRect.Bottom + 1), new Point(i.TextRect.Right, i.TextRect.Bottom + 1)); //Padding between items. x += 16; } sdc.DrawImage(back_bmp, new Point(0, 0)); } /// /// Redraws the Tool Bar by creating a Graphics object. /// public void Redraw() { Draw(CreateGraphics()); } /// /// Paints the control. /// /// Paint event object. protected override void OnPaint(PaintEventArgs pe) { Draw(pe.Graphics); // Calling the base class OnPaint base.OnPaint(pe); } /// /// Stores the items in the Tool Bar. /// private List items; /// /// Accesses or modifies the items in the tool bar. /// /// Index of item. /// ToolBarItem describing the item at index i. public ToolBarItem this[int i] { get { return items[i]; } set { items[i] = value; Redraw(); } } public List Items { get { return items; } set { items = value; } } } public class ToolBarItem { /// /// Tool bar item text. /// [Description("Tool bar item text")] public string Text { get { return text; } set { text = value; } } /// /// Item bitmap. /// [Description("Item Bitmap")] public Bitmap Bitmap { get { return bitmap; } set { bitmap = value; } } /// /// Item drop-down menu /// public ContextMenuStrip Menu { get { return menu; } set { menu = value; } } /// /// Item click event handler /// public event ToolbarItemClickedEventFunction ToolbarItemClicked; public delegate void ToolbarItemClickedEventFunction(object sender, EventArgs e); internal void OnToolbarItemClicked(object sender) { if (ToolbarItemClicked != null) ToolbarItemClicked(sender, new EventArgs()); } private string text; private Bitmap bitmap; private ContextMenuStrip menu; /// /// Stores the rectangle of this item. /// internal Rectangle Rectangle = new Rectangle(); /// /// Stores the rectangle of the bitmap. /// internal Rectangle BitmapRect; /// /// Stores the rectangle of the text. /// internal Rectangle TextRect; /// /// Stores the rectangle of the drop-down arrow. /// internal Rectangle MenuRect; } }