-//
// System.Windows.Forms.ToolBar.cs
//
// Permission is hereby granted, free of charge, to any person obtaining
//
// Author:
// Ravindra (rkumar@novell.com)
+// Mike Kestner <mkestner@novell.com>
//
// TODO:
// - Tooltip
//
-// Copyright (C) Novell, Inc. 2004 (http://www.novell.com)
+// Copyright (C) 2004-2006 Novell, Inc. (http://www.novell.com)
//
public class ToolBar : Control
{
#region Instance Variables
- internal ToolBarAppearance appearance;
- internal bool autosize;
- internal ToolBarButtonCollection buttons;
- internal Size buttonSize;
- internal bool divider;
- internal bool dropDownArrows;
- internal ImageList imageList;
- internal ImeMode imeMode;
- internal bool showToolTips;
- internal ToolBarTextAlign textAlignment;
- internal bool wrappable; // flag to make the toolbar wrappable
- internal bool redraw; // flag to force redrawing the control
- private bool size_specified; // flag to know if button size is fixed.
- internal ToolBarButton currentButton; // the highlighted button
+ bool size_specified = false;
+ ToolBarButton current_button;
#endregion Instance Variables
#region Events
+ static object ButtonClickEvent = new object ();
+ static object ButtonDropDownEvent = new object ();
+
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler BackColorChanged;
+ public new event EventHandler BackColorChanged {
+ add { base.BackColorChanged += value; }
+ remove { base.BackColorChanged -= value; }
+ }
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler BackgroundImageChanged;
+ public new event EventHandler BackgroundImageChanged {
+ add { base.BackgroundImageChanged += value; }
+ remove { base.BackgroundImageChanged -= value; }
+ }
+
+ public event ToolBarButtonClickEventHandler ButtonClick {
+ add { Events.AddHandler (ButtonClickEvent, value); }
+ remove {Events.RemoveHandler (ButtonClickEvent, value); }
+ }
- public event ToolBarButtonClickEventHandler ButtonClick;
- public event ToolBarButtonClickEventHandler ButtonDropDown;
+ public event ToolBarButtonClickEventHandler ButtonDropDown {
+ add { Events.AddHandler (ButtonDropDownEvent, value); }
+ remove {Events.RemoveHandler (ButtonDropDownEvent, value); }
+ }
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler ForeColorChanged;
+ public new event EventHandler ForeColorChanged {
+ add { base.ForeColorChanged += value; }
+ remove { base.ForeColorChanged -= value; }
+ }
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler ImeModeChanged;
+ public new event EventHandler ImeModeChanged {
+ add { base.ImeModeChanged += value; }
+ remove { base.ImeModeChanged -= value; }
+ }
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event PaintEventHandler Paint;
+ public new event PaintEventHandler Paint {
+ add { base.Paint += value; }
+ remove { base.Paint -= value; }
+ }
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler RightToLeftChanged;
+ public new event EventHandler RightToLeftChanged {
+ add { base.RightToLeftChanged += value; }
+ remove { base.RightToLeftChanged -= value; }
+ }
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler TextChanged;
+ public new event EventHandler TextChanged {
+ add { base.TextChanged += value; }
+ remove { base.TextChanged -= value; }
+ }
#endregion Events
#region Constructor
public ToolBar ()
{
- appearance = ToolBarAppearance.Normal;
- autosize = true;
background_color = ThemeEngine.Current.DefaultControlBackColor;
- border_style = BorderStyle.None;
- buttons = new ToolBarButtonCollection (this);
- buttonSize = Size.Empty;
- divider = true;
- dropDownArrows = false;
foreground_color = ThemeEngine.Current.DefaultControlForeColor;
- showToolTips = false;
- textAlignment = ToolBarTextAlign.Underneath;
- wrappable = true;
+ buttons = new ToolBarButtonCollection (this);
dock_style = DockStyle.Top;
- redraw = true;
- size_specified = false;
- // event handlers
- this.MouseDown += new MouseEventHandler (ToolBar_MouseDown);
- this.MouseLeave += new EventHandler (ToolBar_MouseLeave);
- this.MouseMove += new MouseEventHandler (ToolBar_MouseMove);
- this.MouseUp += new MouseEventHandler (ToolBar_MouseUp);
- base.Paint += new PaintEventHandler (ToolBar_Paint);
-
+ GotFocus += new EventHandler (FocusChanged);
+ LostFocus += new EventHandler (FocusChanged);
+ MouseDown += new MouseEventHandler (ToolBar_MouseDown);
+ MouseHover += new EventHandler (ToolBar_MouseHover);
+ MouseLeave += new EventHandler (ToolBar_MouseLeave);
+ MouseMove += new MouseEventHandler (ToolBar_MouseMove);
+ MouseUp += new MouseEventHandler (ToolBar_MouseUp);
+ BackgroundImageChanged += new EventHandler (ToolBar_BackgroundImageChanged);
+
+ TabStop = false;
+
SetStyle (ControlStyles.UserPaint, false);
SetStyle (ControlStyles.FixedHeight, true);
}
}
#endregion
+ ToolBarAppearance appearance = ToolBarAppearance.Normal;
+
#region Public Properties
[DefaultValue (ToolBarAppearance.Normal)]
[Localizable (true)]
return;
appearance = value;
- Redraw (false);
+ Redraw (true);
}
}
+ bool autosize = true;
+
[DefaultValue (true)]
[Localizable (true)]
- public bool AutoSize {
+ public new bool AutoSize {
get { return autosize; }
set {
if (value == autosize)
return;
background_color = value;
- if (BackColorChanged != null)
- BackColorChanged (this, new EventArgs ());
+ OnBackColorChanged (EventArgs.Empty);
Redraw (false);
}
}
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
public override Image BackgroundImage {
- get { return background_image; }
- set {
- if (value == background_image)
- return;
-
- background_image = value;
- if (BackgroundImageChanged != null)
- BackgroundImageChanged (this, new EventArgs ());
- Redraw (false);
- }
+ get { return base.BackgroundImage; }
+ set { base.BackgroundImage = value; }
}
[DefaultValue (BorderStyle.None)]
set { InternalBorderStyle = value; }
}
+ ToolBarButtonCollection buttons;
+
[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
[Localizable (true)]
[MergableProperty (false)]
get { return buttons; }
}
+ Size button_size;
+
[Localizable (true)]
[RefreshProperties (RefreshProperties.All)]
public Size ButtonSize {
get {
- if (buttonSize.IsEmpty) {
+ if (button_size.IsEmpty) {
if (buttons.Count == 0)
- return new Size (39, 36);
+ return new Size (24, 22);
+ Size result = CalcButtonSize ();
+ if (result.IsEmpty)
+ return new Size (24, 22);
else
- return CalcButtonSize ();
+ return result;
}
- return buttonSize;
+ return button_size;
}
set {
- if (buttonSize.Width == value.Width && buttonSize.Height == value.Height)
+ size_specified = value != Size.Empty;
+ if (button_size == value)
return;
- buttonSize = value;
- size_specified = true;
- Redraw (true);
+ button_size = value;
+ Redraw (true);
}
}
+ bool divider = true;
+
[DefaultValue (true)]
public bool Divider {
get { return divider; }
set { base.Dock = value; }
}
+ bool drop_down_arrows = true;
+
[DefaultValue (false)]
[Localizable (true)]
public bool DropDownArrows {
- get { return dropDownArrows; }
+ get { return drop_down_arrows; }
set {
- if (value == dropDownArrows)
+ if (value == drop_down_arrows)
return;
- dropDownArrows = value;
+ drop_down_arrows = value;
Redraw (true);
}
}
return;
foreground_color = value;
- if (ForeColorChanged != null)
- ForeColorChanged (this, new EventArgs ());
+ OnForeColorChanged (EventArgs.Empty);
Redraw (false);
}
}
+ ImageList image_list;
+
[DefaultValue (null)]
public ImageList ImageList {
- get { return imageList; }
- set { imageList = value; }
+ get { return image_list; }
+ set {
+ if (image_list == value)
+ return;
+ image_list = value;
+ Redraw (true);
+ }
}
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Advanced)]
public Size ImageSize {
get {
- if (imageList == null)
+ if (ImageList == null)
return Size.Empty;
- return imageList.ImageSize;
+ return ImageList.ImageSize;
}
}
+ // XXX this should probably go away and it should call
+ // into Control.ImeMode instead.
+ new ImeMode ime_mode = ImeMode.Disable;
+
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
public new ImeMode ImeMode {
- get { return imeMode; }
+ get { return ime_mode; }
set {
- if (value == imeMode)
+ if (value == ime_mode)
return;
- imeMode = value;
- if (ImeModeChanged != null)
- ImeModeChanged (this, new EventArgs ());
+ ime_mode = value;
+ OnImeModeChanged (EventArgs.Empty);
}
}
return;
base.RightToLeft = value;
- if (RightToLeftChanged != null)
- RightToLeftChanged (this, new EventArgs ());
+ OnRightToLeftChanged (EventArgs.Empty);
}
}
+ // Default value is "false" but after make a test in .NET we get "true" result as default.
+ bool show_tooltips = true;
+
[DefaultValue (false)]
[Localizable (true)]
public bool ShowToolTips {
- get { return showToolTips; }
- set { showToolTips = value; }
+ get { return show_tooltips; }
+ set { show_tooltips = value; }
}
[DefaultValue (false)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
[EditorBrowsable (EditorBrowsableState.Never)]
public override string Text {
- get { return text; }
+ get { return base.Text; }
set {
- if (value == text)
+ if (value == base.Text)
return;
- text = value;
+ base.Text = value;
Redraw (true);
- if (TextChanged != null)
- TextChanged (this, new EventArgs ());
}
}
+ ToolBarTextAlign text_alignment = ToolBarTextAlign.Underneath;
+
[DefaultValue (ToolBarTextAlign.Underneath)]
[Localizable (true)]
public ToolBarTextAlign TextAlign {
- get { return textAlignment; }
+ get { return text_alignment; }
set {
- if (value == textAlignment)
+ if (value == text_alignment)
return;
- textAlignment = value;
+ text_alignment = value;
Redraw (true);
}
}
+ bool wrappable = true;
+
[DefaultValue (true)]
[Localizable (true)]
public bool Wrappable {
int count = this.Buttons.Count;
if (count == 0)
- return string.Format ("System.Windows.Forms.ToolBar, Button.Count: 0");
+ return string.Format ("System.Windows.Forms.ToolBar, Buttons.Count: 0");
else
- return string.Format ("System.Windows.Forms.ToolBar, Button.Count: {0}, Buttons[0]: {1}",
+ return string.Format ("System.Windows.Forms.ToolBar, Buttons.Count: {0}, Buttons[0]: {1}",
count, this.Buttons [0].ToString ());
}
#endregion Public Methods
- #region Internal Methods
- internal Rectangle GetChildBounds (ToolBarButton button)
- {
- if (button.Style == ToolBarButtonStyle.Separator)
- return new Rectangle (button.Location.X, button.Location.Y,
- ThemeEngine.Current.ToolBarSeparatorWidth, this.ButtonSize.Height);
-
- if (size_specified)
- return new Rectangle (button.Location, this.ButtonSize);
-
- SizeF sz = this.DeviceContext.MeasureString (button.Text, this.Font);
- Size size = new Size ((int) Math.Ceiling (sz.Width), (int) Math.Ceiling (sz.Height));
-
- if (imageList != null) {
- // adjustment for the image grip
- int imgWidth = this.ImageSize.Width + 2 * ThemeEngine.Current.ToolBarImageGripWidth;
- int imgHeight = this.ImageSize.Height + 2 * ThemeEngine.Current.ToolBarImageGripWidth;
-
- if (textAlignment == ToolBarTextAlign.Right) {
- size.Width = imgWidth + size.Width;
- size.Height = (size.Height > imgHeight) ? size.Height : imgHeight;
- }
- else {
- size.Height = imgHeight + size.Height;
- size.Width = (size.Width > imgWidth) ? size.Width : imgWidth;
- }
- }
- if (button.Style == ToolBarButtonStyle.DropDownButton && this.dropDownArrows)
- size.Width += ThemeEngine.Current.ToolBarDropDownWidth;
-
- return new Rectangle (button.Location, size);
- }
- #endregion Internal Methods
-
#region Protected Methods
protected override void CreateHandle ()
{
protected override void Dispose (bool disposing)
{
if (disposing)
- imageList = null;
+ ImageList = null;
base.Dispose (disposing);
}
}
e.Button.pressed = false;
- Invalidate (e.Button.Rectangle);
- Redraw (false);
+ e.Button.Invalidate ();
- if (ButtonClick != null)
- ButtonClick (this, e);
- else
- return;
+ ToolBarButtonClickEventHandler eh = (ToolBarButtonClickEventHandler)(Events [ButtonClickEvent]);
+ if (eh != null)
+ eh (this, e);
}
protected virtual void OnButtonDropDown (ToolBarButtonClickEventArgs e)
{
- // Reset the flag set on DropDown
- e.Button.dd_pressed = false;
-
- if (ButtonDropDown != null)
- ButtonDropDown (this, e);
+ ToolBarButtonClickEventHandler eh = (ToolBarButtonClickEventHandler)(Events [ButtonDropDownEvent]);
+ if (eh != null)
+ eh (this, e);
if (e.Button.DropDownMenu == null)
return;
- Point loc = new Point (e.Button.Location.X + 1,
- e.Button.Rectangle.Bottom + 2);
+ Point loc = new Point (e.Button.Rectangle.X + 1, e.Button.Rectangle.Bottom + 1);
((ContextMenu) e.Button.DropDownMenu).Show (this, loc);
+
+ e.Button.dd_pressed = false;
+ Invalidate (e.Button.Rectangle);
}
protected override void OnFontChanged (EventArgs e)
{
base.OnResize (e);
- if (this.Width <= 0 || this.Height <= 0 || this.Visible == false)
+ if (Width <= 0 || Height <= 0 || !Visible)
return;
- Redraw (true);
+ Redraw (true, BackgroundImage != null);
}
+ int requested_height = -1;
+
protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
{
+ // New height requested
+ if (!AutoSize && (requested_height != height) && ((specified & BoundsSpecified.Height) != BoundsSpecified.None))
+ requested_height = height;
+
base.SetBoundsCore (x, y, width, height, specified);
}
base.WndProc (ref m);
}
+ internal override bool InternalPreProcessMessage (ref Message msg)
+ {
+ if (msg.Msg == (int)Msg.WM_KEYDOWN) {
+ Keys key_data = (Keys)msg.WParam.ToInt32();
+ if (HandleKeyDown (key_data))
+ return true;
+ }
+ return base.InternalPreProcessMessage (ref msg);
+ }
+
#endregion Protected Methods
#region Private Methods
+ private void FocusChanged (object sender, EventArgs args)
+ {
+ if (Appearance != ToolBarAppearance.Flat || Buttons.Count == 0)
+ return;
+
+ ToolBarButton prelit = null;
+ foreach (ToolBarButton b in Buttons)
+ if (b.Hilight) {
+ prelit = b;
+ break;
+ }
+
+ if (Focused && prelit == null)
+ foreach (ToolBarButton btn in Buttons) {
+ if (btn.Enabled) {
+ btn.Hilight = true;
+ break;
+ }
+ }
+ else if (prelit != null)
+ prelit.Hilight = false;
+ }
+
+ private bool HandleKeyDown (Keys key_data)
+ {
+ if (Appearance != ToolBarAppearance.Flat || Buttons.Count == 0)
+ return false;
+
+ switch (key_data) {
+ case Keys.Left:
+ case Keys.Up:
+ HighlightButton (-1);
+ return true;
+ case Keys.Right:
+ case Keys.Down:
+ HighlightButton (1);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ void HighlightButton (int offset)
+ {
+ ArrayList enabled = new ArrayList ();
+ int count = 0;
+ int start = -1;
+ ToolBarButton curr_button = null;
+ foreach (ToolBarButton btn in Buttons) {
+ if (btn.Hilight) {
+ start = count;
+ curr_button = btn;
+ }
+
+ if (btn.Enabled) {
+ enabled.Add (btn);
+ count++;
+ }
+ }
+
+ int next = (start + offset) % count;
+ if (next < 0)
+ next = count - 1;
+
+ if (next == start)
+ return;
+
+ if (curr_button != null)
+ curr_button.Hilight = false;
+ (enabled [next] as ToolBarButton).Hilight = true;
+ }
+
+ private void ToolBar_BackgroundImageChanged (object sender, EventArgs args)
+ {
+ Redraw (false);
+ }
+
private void ToolBar_MouseDown (object sender, MouseEventArgs me)
{
- if (! this.Enabled) return;
+ if ((!Enabled) || ((me.Button & MouseButtons.Left) == 0))
+ return;
- Point hit = new Point (me.X, me.Y);
- this.Capture = true;
+ Point loc = new Point (me.X, me.Y);
+ if (ButtonAtPoint (loc) == null)
+ return;
+
+ // Hide tooltip when left mouse button
+ if ((tip_window != null) && (tip_window.Visible) && ((me.Button & MouseButtons.Left) == MouseButtons.Left)) {
+ TipDownTimer.Stop ();
+ tip_window.Hide ();
+ }
+
// draw the pushed button
foreach (ToolBarButton button in buttons) {
- if (button.Enabled && button.Rectangle.Contains (hit)) {
+ if (button.Enabled && button.Rectangle.Contains (loc)) {
// Mark the DropDown rect as pressed.
// We don't redraw the dropdown rect.
if (button.Style == ToolBarButtonStyle.DropDownButton) {
- Rectangle ddRect = Rectangle.Empty;
Rectangle rect = button.Rectangle;
- ddRect.Height = rect.Height;
- ddRect.Width = ThemeEngine.Current.ToolBarDropDownWidth;
- ddRect.X = rect.X + rect.Width - ddRect.Width;
- ddRect.Y = rect.Y;
- if (ddRect.Contains (hit)) {
- button.dd_pressed = true;
+ if (DropDownArrows) {
+ rect.Width = ThemeEngine.Current.ToolBarDropDownWidth;
+ rect.X = button.Rectangle.Right - rect.Width;
+ }
+
+ if (rect.Contains (loc)) {
+ if (button.DropDownMenu != null) {
+ button.dd_pressed = true;
+ Invalidate (rect);
+ }
break;
}
}
- // If it is not dropdown then we treat it as a normal
- // button press.
button.pressed = true;
button.inside = true;
- Invalidate (button.Rectangle);
- Redraw (false);
+ button.Invalidate ();
break;
}
}
private void ToolBar_MouseUp (object sender, MouseEventArgs me)
{
- if (! this.Enabled) return;
+ if ((!Enabled) || ((me.Button & MouseButtons.Left) == 0))
+ return;
- Point hit = new Point (me.X, me.Y);
- this.Capture = false;
+ Point loc = new Point (me.X, me.Y);
// draw the normal button
+ // Make a copy in case the list is modified during enumeration
+ ArrayList buttons = new ArrayList (this.buttons);
foreach (ToolBarButton button in buttons) {
- if (button.Enabled && button.Rectangle.Contains (hit)) {
+ if (button.Enabled && button.Rectangle.Contains (loc)) {
if (button.Style == ToolBarButtonStyle.DropDownButton) {
- Rectangle ddRect = Rectangle.Empty;
- Rectangle rect = button.Rectangle;
- ddRect.Height = rect.Height;
+ Rectangle ddRect = button.Rectangle;
ddRect.Width = ThemeEngine.Current.ToolBarDropDownWidth;
- ddRect.X = rect.X + rect.Width - ddRect.Width;
- ddRect.Y = rect.Y;
- // Fire a ButtonDropDown event
- if (ddRect.Contains (hit)) {
+ ddRect.X = button.Rectangle.Right - ddRect.Width;
+ if (ddRect.Contains (loc)) {
if (button.dd_pressed)
- this.OnButtonDropDown (new ToolBarButtonClickEventArgs (button));
+ OnButtonDropDown (new ToolBarButtonClickEventArgs (button));
continue;
}
}
// Fire a ButtonClick
- if (button.pressed)
- this.OnButtonClick (new ToolBarButtonClickEventArgs (button));
- }
- // Clear the button press flags, if any
- else if (button.pressed) {
+ if ((button.pressed) && ((me.Button & MouseButtons.Left) == MouseButtons.Left))
+ OnButtonClick (new ToolBarButtonClickEventArgs (button));
+ } else if (button.pressed) {
button.pressed = false;
- Invalidate (button.Rectangle);
- Redraw (false);
+ button.Invalidate ();
}
}
}
- private void ToolBar_MouseLeave (object sender, EventArgs e)
+ private ToolBarButton ButtonAtPoint (Point pt)
{
- if (! this.Enabled || appearance != ToolBarAppearance.Flat) return;
+ foreach (ToolBarButton button in buttons)
+ if (button.Rectangle.Contains (pt))
+ return button;
- if (currentButton != null && currentButton.Hilight) {
- currentButton.Hilight = false;
- Invalidate (currentButton.Rectangle);
- Redraw (false);
+ return null;
+ }
+
+ ToolTip.ToolTipWindow tip_window = null;
+ Timer tipdown_timer = null;
+
+ private void PopDownTip (object o, EventArgs args)
+ {
+ tip_window.Hide ();
+ }
+
+ private Timer TipDownTimer {
+ get {
+ if (tipdown_timer == null) {
+ tipdown_timer = new Timer ();
+ tipdown_timer.Enabled = false;
+ tipdown_timer.Interval = 5000;
+ tipdown_timer.Tick += new EventHandler (PopDownTip);
+ }
+ return tipdown_timer;
}
- currentButton = null;
+ }
+
+ private void ToolBar_MouseHover (object sender, EventArgs e)
+ {
+ if (Capture)
+ return;
+
+ if (tip_window == null)
+ tip_window = new ToolTip.ToolTipWindow ();
+
+ ToolBarButton btn = ButtonAtPoint (PointToClient (Control.MousePosition));
+ current_button = btn;
+
+ if (btn == null || btn.ToolTipText.Length == 0)
+ return;
+
+ tip_window.Present (this, btn.ToolTipText);
+ TipDownTimer.Start ();
+ }
+
+ private void ToolBar_MouseLeave (object sender, EventArgs e)
+ {
+ if (tipdown_timer != null)
+ tipdown_timer.Dispose ();
+ tipdown_timer = null;
+ if (tip_window != null)
+ tip_window.Dispose ();
+ tip_window = null;
+
+ if (!Enabled || current_button == null)
+ return;
+
+ current_button.Hilight = false;
+ current_button = null;
}
private void ToolBar_MouseMove (object sender, MouseEventArgs me)
{
- if (! this.Enabled) return;
+ if (!Enabled)
+ return;
+
+ if (tip_window != null && tip_window.Visible) {
+ TipDownTimer.Stop ();
+ TipDownTimer.Start ();
+ }
- Point hit = new Point (me.X, me.Y);
+ Point loc = new Point (me.X, me.Y);
- if (this.Capture) {
+ if (Capture) {
// If the button was pressed and we leave, release the
// button press and vice versa
foreach (ToolBarButton button in buttons) {
if (button.pressed &&
- (button.inside != button.Rectangle.Contains (hit))) {
- button.inside = button.Rectangle.Contains (hit);
+ (button.inside != button.Rectangle.Contains (loc))) {
+ button.inside = button.Rectangle.Contains (loc);
button.Hilight = false;
- Invalidate (button.Rectangle);
- Redraw (false);
break;
}
}
- }
- // following is only for flat style toolbar
- else if (appearance == ToolBarAppearance.Flat) {
- if (currentButton != null && currentButton.Rectangle.Contains (hit)) {
- if (currentButton.Hilight || currentButton.Pushed)
+ return;
+ }
+
+ if (current_button != null && current_button.Rectangle.Contains (loc)) {
+ if (appearance == ToolBarAppearance.Flat) {
+ if (current_button.Hilight || current_button.Pushed || !current_button.Enabled)
return;
- currentButton.Hilight = true;
- Invalidate (currentButton.Rectangle);
- Redraw (false);
+ current_button.Hilight = true;
}
- else {
+ } else {
+ if (tip_window != null) {
+ if (tip_window.Visible) {
+ tip_window.Hide ();
+ TipDownTimer.Stop ();
+ }
+ current_button = ButtonAtPoint (loc);
+ if (current_button != null && current_button.ToolTipText.Length > 0) {
+ tip_window.Present (this, current_button.ToolTipText);
+ TipDownTimer.Start ();
+ }
+ }
+
+ if (appearance == ToolBarAppearance.Flat) {
foreach (ToolBarButton button in buttons) {
- if (button.Rectangle.Contains (hit) && button.Enabled) {
- currentButton = button;
- if (currentButton.Hilight || currentButton.Pushed)
+ if (button.Rectangle.Contains (loc) && button.Enabled) {
+ current_button = button;
+ if (current_button.Hilight || current_button.Pushed)
continue;
- currentButton.Hilight = true;
- Invalidate (currentButton.Rectangle);
- Redraw (false);
+ current_button.Hilight = true;
}
else if (button.Hilight) {
button.Hilight = false;
- Invalidate (button.Rectangle);
- Redraw (false);
}
}
}
}
}
- private void ToolBar_Paint (object sender, PaintEventArgs pevent)
+ internal override void OnPaintInternal (PaintEventArgs pevent)
{
ThemeEngine.Current.DrawToolBar (pevent.Graphics, pevent.ClipRectangle, this);
-
- if (Paint != null) {
- Paint (this, pevent);
- }
}
internal void Redraw (bool recalculate)
{
- // if (recalculate) {
- CalcToolBar ();
- // }
+ Redraw (recalculate, true);
+ }
+
+ internal void Redraw (bool recalculate, bool force)
+ {
+ bool invalidate = true;
+ if (recalculate) {
+ invalidate = LayoutToolBar ();
+ }
+
+ if (force || invalidate)
+ Invalidate ();
+ }
- redraw = true;
- Refresh ();
+ internal bool SizeSpecified {
+ get { return size_specified; }
}
+ const int text_padding = 3;
+
private Size CalcButtonSize ()
{
- String longestText = buttons [0].Text;
- for (int i = 1; i < buttons.Count; i++) {
- if (buttons[i].Text.Length > longestText.Length)
- longestText = buttons[i].Text;
+ if (Buttons.Count == 0)
+ return Size.Empty;
+
+ string longest_text = Buttons [0].Text;
+ for (int i = 1; i < Buttons.Count; i++) {
+ if (Buttons[i].Text.Length > longest_text.Length)
+ longest_text = Buttons[i].Text;
}
- SizeF sz = this.DeviceContext.MeasureString (longestText, this.Font);
- Size size = new Size ((int) Math.Ceiling (sz.Width), (int) Math.Ceiling (sz.Height));
+ Size size = Size.Empty;
+ if (longest_text != null && longest_text.Length > 0) {
+ SizeF sz = DeviceContext.MeasureString (longest_text, Font);
+ if (sz != SizeF.Empty)
+ size = new Size ((int) Math.Ceiling (sz.Width) + 2 * text_padding, (int) Math.Ceiling (sz.Height));
+ }
- if (imageList != null) {
- // adjustment for the image grip
- int imgWidth = this.ImageSize.Width + 2 * ThemeEngine.Current.ToolBarImageGripWidth;
- int imgHeight = this.ImageSize.Height + 2 * ThemeEngine.Current.ToolBarImageGripWidth;
+ Size img_size = ImageList == null ? new Size (16, 16) : ImageSize;
- if (textAlignment == ToolBarTextAlign.Right) {
- size.Width = imgWidth + size.Width;
- size.Height = (size.Height > imgHeight) ? size.Height : imgHeight;
- }
- else {
- size.Height = imgHeight + size.Height;
- size.Width = (size.Width > imgWidth) ? size.Width : imgWidth;
- }
+ Theme theme = ThemeEngine.Current;
+ int imgWidth = img_size.Width + 2 * theme.ToolBarImageGripWidth;
+ int imgHeight = img_size.Height + 2 * theme.ToolBarImageGripWidth;
+
+ if (text_alignment == ToolBarTextAlign.Right) {
+ size.Width = imgWidth + size.Width;
+ size.Height = (size.Height > imgHeight) ? size.Height : imgHeight;
+ } else {
+ size.Height = imgHeight + size.Height;
+ size.Width = (size.Width > imgWidth) ? size.Width : imgWidth;
}
+
+ size.Width += theme.ToolBarImageGripWidth;
+ size.Height += theme.ToolBarImageGripWidth;
return size;
}
- /* Checks for the separators and sets the location of a button and its wrapper flag */
- private void CalcToolBar ()
- {
- int wd = this.Width; // the amount of space we have for rest of the buttons
- int ht = this.ButtonSize.Height; // all buttons are displayed with the same height
- Point loc; // the location to place the next button, leave the space for border
- loc = new Point (ThemeEngine.Current.ToolBarGripWidth, ThemeEngine.Current.ToolBarGripWidth);
-
- // clear all the wrappers if toolbar is not wrappable
- if (! wrappable && ! autosize) {
- if (this.Height != this.DefaultSize.Height)
- this.Height = this.DefaultSize.Height;
- foreach (ToolBarButton button in buttons) {
- button.Location = loc;
- button.Wrapper = false;
- loc.X = loc.X + button.Rectangle.Width;
- }
- }
- else if (! wrappable) { // autosizeable
- if (ht != this.Height)
- this.Height = ht;
- foreach (ToolBarButton button in buttons) {
- button.Location = loc;
- button.Wrapper = false;
- loc.X = loc.X + button.Rectangle.Width;
- }
- }
- else { // wrappable
- bool seenSeparator = false;
- int separatorIndex = -1;
- ToolBarButton button;
-
- for (int i = 0; i < buttons.Count; i++) {
- button = buttons [i];
- if (button.Visible) {
- if (button.Style == ToolBarButtonStyle.Separator) {
- wd -= ThemeEngine.Current.ToolBarSeparatorWidth;
- if (wd > 0) {
- button.Wrapper = false; // clear the old flag in case it was set
- button.Location = loc;
- loc.X = loc.X + ThemeEngine.Current.ToolBarSeparatorWidth;
- }
- else {
- button.Wrapper = true;
- button.Location = loc;
- loc.X = ThemeEngine.Current.ToolBarGripWidth;
- wd = this.Width;
- // we need space to draw horizontal separator
- loc.Y = loc.Y + ThemeEngine.Current.ToolBarSeparatorWidth + ht;
- }
- seenSeparator = true;
- separatorIndex = i;
- }
- else {
- Rectangle rect = button.Rectangle;
- wd -= rect.Width;
- if (wd > 0) {
- button.Wrapper = false;
- button.Location = loc;
- loc.X = loc.X + rect.Width;
- }
- else if (seenSeparator) {
- // wrap at the separator and reassign the locations
- i = separatorIndex; // for loop is going to increment it
- buttons [separatorIndex].Wrapper = true;
- seenSeparator = false;
- separatorIndex = -1;
- loc.X = ThemeEngine.Current.ToolBarGripWidth;
- // we need space to draw horizontal separator
- loc.Y = loc.Y + ht + ThemeEngine.Current.ToolBarSeparatorWidth;
- wd = this.Width;
- continue;
- }
- else {
- button.Wrapper = true;
- wd = this.Width;
- loc.X = 0;
- loc.Y += ht;
- button.Location = loc;
- loc.X = loc.X + rect.Width;
- }
- }
+ // Flat toolbars disregard specified sizes. Normal toolbars grow the
+ // button size to be at least large enough to show the image.
+ Size AdjustedButtonSize {
+ get {
+ Size size = ButtonSize;
+ if (size_specified) {
+ if (Appearance == ToolBarAppearance.Flat)
+ size = CalcButtonSize ();
+ else {
+ int grip = ThemeEngine.Current.ToolBarImageGripWidth;
+ if (size.Width < ImageSize.Width + 2 * grip )
+ size.Width = ImageSize.Width + 2 * grip;
+ if (size.Height < ImageSize.Height + 2 * grip)
+ size.Height = ImageSize.Height + 2 * grip;
}
- else // don't consider invisible buttons
- continue;
}
- /* adjust the control height, if we are autosizeable */
- if (autosize) // wrappable
- if (this.Height != (loc.Y + ht + ThemeEngine.Current.ToolBarGripWidth))
- this.Height = loc.Y + ht + ThemeEngine.Current.ToolBarGripWidth;
+ return size;
}
}
- private void DumpToolBar (string msg)
+ bool LayoutToolBar ()
{
- Console.WriteLine (msg);
- Console.WriteLine ("ToolBar: name: " + this.Text);
- Console.WriteLine ("ToolBar: wd, ht: " + this.Size);
- Console.WriteLine ("ToolBar: img size: " + this.ImageSize);
- Console.WriteLine ("ToolBar: button sz: " + this.buttonSize);
- Console.WriteLine ("ToolBar: textalignment: "+ this.TextAlign);
- Console.WriteLine ("ToolBar: appearance: "+ this.Appearance);
- Console.WriteLine ("ToolBar: wrappable: "+ this.Wrappable);
- Console.WriteLine ("ToolBar: buttons count: " + this.Buttons.Count);
-
- int i= 0;
- foreach (ToolBarButton b in buttons) {
- Console.WriteLine ("ToolBar: button [{0}]:",i++);
- b.Dump ();
+ bool changed = false;
+ Theme theme = ThemeEngine.Current;
+ int x = theme.ToolBarGripWidth;
+ int y = theme.ToolBarGripWidth;
+
+ Size adjusted_size = AdjustedButtonSize;
+ int ht = adjusted_size.Height + theme.ToolBarGripWidth;
+
+ int separator_index = -1;
+
+ for (int i = 0; i < buttons.Count; i++) {
+ ToolBarButton button = buttons [i];
+
+ if (!button.Visible)
+ continue;
+
+ if (size_specified && (button.Style != ToolBarButtonStyle.Separator))
+ changed = button.Layout (adjusted_size);
+ else
+ changed = button.Layout ();
+
+ bool is_separator = button.Style == ToolBarButtonStyle.Separator;
+
+ if (x + button.Rectangle.Width < Width || is_separator || !Wrappable) {
+ if (button.Location.X != x || button.Location.Y != y)
+ changed = true;
+ button.Location = new Point (x, y);
+ x += button.Rectangle.Width;
+ if (is_separator)
+ separator_index = i;
+ } else if (separator_index > 0) {
+ i = separator_index;
+ separator_index = -1;
+ x = theme.ToolBarGripWidth;
+ y += ht;
+ } else {
+ x = theme.ToolBarGripWidth;
+ y += ht;
+ if (button.Location.X != x || button.Location.Y != y)
+ changed = true;
+ button.Location = new Point (x, y);
+ x += button.Rectangle.Width;
+ }
}
+
+ if (Parent == null)
+ return changed;
+
+ if (AutoSize)
+ Height = ht + (Wrappable ? y : 0);
+ else
+ Height = requested_height;
+
+ return changed;
}
#endregion Private Methods
public class ToolBarButtonCollection : IList, ICollection, IEnumerable
{
#region instance variables
- private ArrayList buttonsList;
+ private ArrayList list;
private ToolBar owner;
+ private bool redraw;
#endregion
#region constructors
public ToolBarButtonCollection (ToolBar owner)
{
this.owner = owner;
- this.buttonsList = new ArrayList ();
+ list = new ArrayList ();
+ redraw = true;
}
#endregion
#region properties
[Browsable (false)]
- public virtual int Count {
- get { return buttonsList.Count; }
+ public int Count {
+ get { return list.Count; }
}
- public virtual bool IsReadOnly {
- get { return buttonsList.IsReadOnly; }
+ public bool IsReadOnly {
+ get { return list.IsReadOnly; }
}
public virtual ToolBarButton this [int index] {
- get { return (ToolBarButton) buttonsList [index]; }
+ get { return (ToolBarButton) list [index]; }
set {
value.SetParent (owner);
- buttonsList [index] = value;
+ list [index] = value;
owner.Redraw (true);
}
}
bool ICollection.IsSynchronized {
- get { return buttonsList.IsSynchronized; }
+ get { return list.IsSynchronized; }
}
object ICollection.SyncRoot {
- get { return buttonsList.SyncRoot; }
+ get { return list.SyncRoot; }
}
bool IList.IsFixedSize {
- get { return buttonsList.IsFixedSize; }
+ get { return list.IsFixedSize; }
}
object IList.this [int index] {
{
int result;
button.SetParent (owner);
- result = buttonsList.Add (button);
- owner.Redraw (true);
+ result = list.Add (button);
+ if (redraw)
+ owner.Redraw (true);
return result;
}
public void AddRange (ToolBarButton [] buttons)
{
- foreach (ToolBarButton button in buttons)
- Add (button);
+ try {
+ redraw = false;
+ foreach (ToolBarButton button in buttons)
+ Add (button);
+ }
+ finally {
+ redraw = true;
+ owner.Redraw (true);
+ }
}
- public virtual void Clear ()
+ public void Clear ()
{
- buttonsList.Clear ();
+ list.Clear ();
owner.Redraw (false);
}
public bool Contains (ToolBarButton button)
{
- return buttonsList.Contains (button);
+ return list.Contains (button);
}
- public virtual IEnumerator GetEnumerator ()
+ public IEnumerator GetEnumerator ()
{
- return buttonsList.GetEnumerator ();
+ return list.GetEnumerator ();
}
void ICollection.CopyTo (Array dest, int index)
{
- buttonsList.CopyTo (dest, index);
+ list.CopyTo (dest, index);
}
int IList.Add (object button)
public int IndexOf (ToolBarButton button)
{
- return buttonsList.IndexOf (button);
+ return list.IndexOf (button);
}
public void Insert (int index, ToolBarButton button)
{
- buttonsList.Insert (index, button);
+ list.Insert (index, button);
owner.Redraw (true);
}
public void Remove (ToolBarButton button)
{
- buttonsList.Remove (button);
+ list.Remove (button);
owner.Redraw (true);
}
- public virtual void RemoveAt (int index)
+ public void RemoveAt (int index)
{
- buttonsList.RemoveAt (index);
+ list.RemoveAt (index);
owner.Redraw (true);
}
#endregion methods