// System.Windows.Forms.ToolBarButton.cs
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (C) 2004-2006 Novell, Inc. (http://www.novell.com)
//
// Authors:
// Ravindra (rkumar@novell.com)
// Mike Kestner <mkestner@novell.com>
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Imaging;
namespace System.Windows.Forms
{
[DefaultProperty ("Text")]
[Designer ("System.Windows.Forms.Design.ToolBarButtonDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
[DesignTimeVisible (false)]
[ToolboxItem (false)]
public class ToolBarButton : Component
{
#region instance variable
private bool enabled = true;
private int image_index = -1;
private ContextMenu menu;
private ToolBar parent;
private bool partial_push = false;
private bool pushed = false;
private ToolBarButtonStyle style = ToolBarButtonStyle.PushButton;
private object tag;
private string text = "";
private string tooltip = "";
private bool visible = true;
internal bool dd_pressed = false; // to check for a mouse down on dropdown rect
internal bool hilight = false; // to hilight buttons in flat style
internal bool inside = false; // to handle the mouse move event with mouse pressed
internal bool pressed = false; // this is to check for mouse down on a button
#endregion
#region constructors
public ToolBarButton () { }
public ToolBarButton (string text)
{
this.text = text;
}
#endregion
#region internal properties
internal bool Hilight {
get { return hilight; }
set {
if (hilight == value)
return;
hilight = value;
InvalidateBorder ();
}
}
internal Image Image {
get {
if (Parent == null || Parent.ImageList == null)
return null;
ImageList list = Parent.ImageList;
if (ImageIndex > -1 && ImageIndex < list.Images.Count)
return list.Images [ImageIndex];
return null;
}
}
Rectangle image_rect;
internal Rectangle ImageRectangle {
get {
Rectangle result = image_rect;
result.X += bounds.X;
result.Y += bounds.Y;
return result;
}
}
Rectangle text_rect;
internal Rectangle TextRectangle {
get {
Rectangle result = text_rect;
result.X += bounds.X;
result.Y += bounds.Y;
return result;
}
}
Rectangle bounds;
internal Point Location {
get { return bounds.Location; }
set {
if (bounds.Location == value)
return;
if (bounds != Rectangle.Empty)
Invalidate ();
bounds.Location = value;
Invalidate ();
}
}
internal bool Pressed {
get {
if (pressed && inside)
return true;
else
return false;
}
set { pressed = value; }
}
#endregion internal properties
#region properties
[DefaultValue (null)]
[TypeConverter (typeof (ReferenceConverter))]
public Menu DropDownMenu {
get { return menu; }
set {
if (value is ContextMenu)
menu = (ContextMenu) value;
else
throw new ArgumentException ("DropDownMenu must be of type ContextMenu.");
}
}
[DefaultValue (true)]
[Localizable (true)]
public bool Enabled {
get { return enabled; }
set {
if (value == enabled)
return;
enabled = value;
Invalidate ();
}
}
[DefaultValue (-1)]
[Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
[Localizable (true)]
[TypeConverter (typeof (ImageIndexConverter))]
public int ImageIndex {
get { return image_index; }
set {
if (value < -1)
throw new ArgumentException ("ImageIndex value must be above or equal to -1.");
if (value == image_index)
return;
image_index = value;
if (bounds.Size != CalculateSize ())
Parent.Redraw (true);
else
Invalidate ();
}
}
[Browsable (false)]
public ToolBar Parent {
get { return parent; }
}
[DefaultValue (false)]
public bool PartialPush {
get { return partial_push; }
set {
if (value == partial_push)
return;
partial_push = value;
Invalidate ();
}
}
[DefaultValue (false)]
public bool Pushed {
get { return pushed; }
set {
if (value == pushed)
return;
pushed = value;
Invalidate ();
}
}
public Rectangle Rectangle {
get {
if (Visible && Parent != null && Parent.Visible) {
Rectangle result = bounds;
if (Style == ToolBarButtonStyle.DropDownButton && Parent.DropDownArrows)
result.Width += ThemeEngine.Current.ToolBarDropDownWidth;
return result;
} else
return Rectangle.Empty;
}
}
[DefaultValue (ToolBarButtonStyle.PushButton)]
[RefreshProperties (RefreshProperties.Repaint)]
public ToolBarButtonStyle Style {
get { return style; }
set {
if (value == style)
return;
style = value;
Invalidate ();
}
}
[Bindable (true)]
[DefaultValue (null)]
[Localizable (false)]
[TypeConverter (typeof (StringConverter))]
public object Tag {
get { return tag; }
set { tag = value; }
}
[DefaultValue ("")]
[Localizable (true)]
public string Text {
get { return text; }
set {
if (value == text)
return;
text = value;
if (Parent != null)
Parent.Redraw (true);
}
}
[DefaultValue ("")]
[Localizable (true)]
public string ToolTipText {
get { return tooltip; }
set { tooltip = value; }
}
[DefaultValue (true)]
[Localizable (true)]
public bool Visible {
get { return visible; }
set {
if (value == visible)
return;
visible = value;
if (Parent != null)
Parent.Redraw (true);
}
}
#endregion
#region internal methods
internal void SetParent (ToolBar parent)
{
if (Parent == parent)
return;
if (Parent != null)
Parent.Buttons.Remove (this);
this.parent = parent;
}
internal bool Layout ()
{
if (Parent == null || !Visible)
return false;
Size psize = Parent.ButtonSize;
Size size = psize;
if (!Parent.SizeSpecified) {
size = CalculateSize ();
if (size.Width == 0 || size.Height == 0)
size = psize;
}
return Layout (size);
}
internal bool Layout (Size size)
{
if (Parent == null || !Visible)
return false;
bounds.Size = size;
Size image_size = (Parent.ImageSize == Size.Empty) ? new Size (16, 16) : Parent.ImageSize;
int grip = ThemeEngine.Current.ToolBarImageGripWidth;
Rectangle new_image_rect, new_text_rect;
if (Parent.TextAlign == ToolBarTextAlign.Underneath) {
new_image_rect = new Rectangle ((bounds.Size.Width - image_size.Width) / 2 - grip, 0, image_size.Width + 2 + grip, image_size.Height + 2 * grip);
new_text_rect = new Rectangle (0, new_image_rect.Height, bounds.Size.Width, bounds.Size.Height - new_image_rect.Height);
} else {
new_image_rect = new Rectangle (0, 0, image_size.Width + 2 * grip, image_size.Height + 2 * grip);
new_text_rect = new Rectangle (new_image_rect.Width, 0, bounds.Size.Width - new_image_rect.Width, bounds.Size.Height);
}
bool changed = false;
if (new_image_rect != image_rect || new_text_rect != text_rect)
changed = true;
image_rect = new_image_rect;
text_rect = new_text_rect;
return changed;
}
const int text_padding = 3;
Size TextSize {
get {
SizeF sz = Parent.DeviceContext.MeasureString (Text, Parent.Font);
if (sz == SizeF.Empty)
return Size.Empty;
return new Size ((int) Math.Ceiling (sz.Width) + 2 * text_padding, (int) Math.Ceiling (sz.Height));
}
}
Size CalculateSize ()
{
if (Parent == null)
return Size.Empty;
Theme theme = ThemeEngine.Current;
int ht = Parent.ButtonSize.Height + 2 * theme.ToolBarGripWidth;
if (Style == ToolBarButtonStyle.Separator)
return new Size (theme.ToolBarSeparatorWidth, ht);
Size size = TextSize;
Size image_size = (Parent.ImageSize == Size.Empty) ? new Size (16, 16) : Parent.ImageSize;
int image_width = image_size.Width + 2 * theme.ToolBarImageGripWidth;
int image_height = image_size.Height + 2 * theme.ToolBarImageGripWidth;
if (Parent.TextAlign == ToolBarTextAlign.Right) {
size.Width = image_width + size.Width;
size.Height = (size.Height > image_height) ? size.Height : image_height;
} else {
size.Height = image_height + size.Height;
size.Width = (size.Width > image_width) ? size.Width : image_width;
}
size.Width += theme.ToolBarGripWidth;
size.Height += theme.ToolBarGripWidth;
return size;
}
internal void InvalidateBorder ()
{
if (ThemeEngine.Current.ToolBarInvalidateEntireButton) {
Invalidate ();
}
else {
if (Rectangle == Rectangle.Empty)
return;
/* invalidate the four sides of our border */
Parent.Invalidate (new Rectangle (Rectangle.X - 2, Rectangle.Y - 2,
Rectangle.Width + 4, 4));
Parent.Invalidate (new Rectangle (Rectangle.X - 2, Rectangle.Y - 2,
4, Rectangle.Height + 4));
Parent.Invalidate (new Rectangle (Rectangle.X - 2, Rectangle.Y + Rectangle.Height - 2,
Rectangle.Width + 4, 4));
Parent.Invalidate (new Rectangle (Rectangle.X + Rectangle.Width - 2, Rectangle.Y - 2,
4, Rectangle.Height + 4));
}
}
void Invalidate ()
{
if (Parent != null)
Parent.Invalidate (Rectangle);
}
#endregion Internal Methods
#region methods
protected override void Dispose (bool disposing)
{
base.Dispose (disposing);
}
public override string ToString ()
{
return string.Format ("ToolBarButton: {0}, Style: {1}", text, style);
}
#endregion
}
}