1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2004-2005 Novell, Inc.
23 // Peter Bartok pbartok@novell.com
28 using System.ComponentModel;
29 using System.ComponentModel.Design;
31 using System.Drawing.Text;
32 using System.Runtime.InteropServices;
34 namespace System.Windows.Forms {
35 public abstract class ButtonBase : Control {
36 #region Local Variables
37 internal FlatStyle flat_style;
38 internal int image_index;
40 internal ImageList image_list;
41 internal ContentAlignment image_alignment;
42 internal ContentAlignment text_alignment;
43 private bool is_default;
44 internal bool is_pressed;
45 internal bool enter_state;
46 internal StringFormat text_format;
47 #endregion // Local Variables
49 #region ButtonBaseAccessibleObject sub-class
51 public class ButtonBaseAccessibleObject : ControlAccessibleObject {
52 #region ButtonBaseAccessibleObject Local Variables
53 private Control owner;
54 #endregion // ButtonBaseAccessibleObject Local Variables
56 #region ButtonBaseAccessibleObject Constructors
57 public ButtonBaseAccessibleObject(Control owner) : base(owner) {
60 #endregion // ButtonBaseAccessibleObject Constructors
62 #region ButtonBaseAccessibleObject Methods
63 public override void DoDefaultAction() {
64 ((ButtonBase)owner).PerformClick();
66 #endregion // ButtonBaseAccessibleObject Methods
68 #endregion // ButtonBaseAccessibleObject sub-class
70 #region Private Properties and Methods
71 internal ButtonState ButtonState {
73 ButtonState ret = ButtonState.Normal;
76 // Popup style is only followed as long as the mouse isn't "in" the control
78 if (flat_style == FlatStyle.Flat) {
79 ret |= ButtonState.Flat;
82 if (flat_style == FlatStyle.Flat || flat_style == FlatStyle.Popup) {
83 ret |= ButtonState.Flat;
87 if (is_entered && is_pressed) {
88 ret |= ButtonState.Pushed;
91 ret |= ButtonState.Inactive;
92 if ((flat_style == FlatStyle.Flat) || (flat_style == FlatStyle.Popup)) {
93 ret |= ButtonState.Flat;
100 [MonoTODO("Make the FillRectangle use a global brush instead of creating one every time")]
101 internal void Redraw() {
105 // Derived classes should override Draw method and we dont want
106 // to break the control signature, hence this approach.
107 internal virtual void Draw (PaintEventArgs pevent) {
108 ThemeEngine.Current.DrawButtonBase (pevent.Graphics, pevent.ClipRectangle, this);
111 internal virtual void HaveDoubleClick() {
115 private void RedrawEvent(object sender, System.EventArgs e) {
119 #endregion // Private Properties and Methods
121 #region Public Constructors
122 protected ButtonBase() : base() {
123 flat_style = FlatStyle.Standard;
127 image_alignment = ContentAlignment.MiddleCenter;
128 text_alignment = ContentAlignment.MiddleCenter;
129 ime_mode = ImeMode.Inherit;
134 text_format = new StringFormat();
135 text_format.Alignment = StringAlignment.Center;
136 text_format.LineAlignment = StringAlignment.Center;
137 text_format.HotkeyPrefix = HotkeyPrefix.Show;
139 TextChanged+=new System.EventHandler(RedrawEvent);
140 ForeColorChanged+=new EventHandler(RedrawEvent);
141 BackColorChanged+=new System.EventHandler(RedrawEvent);
142 FontChanged+=new EventHandler(RedrawEvent);
143 SizeChanged+=new EventHandler(RedrawEvent);
145 SetStyle(ControlStyles.ResizeRedraw |
146 ControlStyles.Opaque |
147 ControlStyles.UserMouse |
148 ControlStyles.SupportsTransparentBackColor |
149 ControlStyles.CacheText |
150 ControlStyles.DoubleBuffer, true);
151 SetStyle(ControlStyles.StandardClick, false);
153 #endregion // Public Constructors
155 #region Public Instance Properties
157 [DefaultValue(FlatStyle.Standard)]
158 [MWFDescription("Determines look of button"), MWFCategory("Appearance")]
159 public FlatStyle FlatStyle {
171 [MWFDescription("Sets image to be displayed on button face"), MWFCategory("Appearance")]
184 [DefaultValue(ContentAlignment.MiddleCenter)]
185 [MWFDescription("Sets the alignment of the image to be displayed on button face"), MWFCategory("Appearance")]
186 public ContentAlignment ImageAlign {
188 return image_alignment;
192 image_alignment=value;
199 [Editor("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
200 [TypeConverter(typeof(ImageIndexConverter))]
201 [MWFDescription("Index of image to display, if ImageList is used for button face images"), MWFCategory("Appearance")]
202 public int ImageIndex {
204 if (image_list==null) {
217 [MWFDescription("ImageList used for ImageIndex"), MWFCategory("Appearance")]
218 public ImageList ImageList {
229 if (image_list.Images.Count >= image_index) {
230 image_index=image_list.Images.Count-1;
238 [EditorBrowsable (EditorBrowsableState.Never)]
239 public new ImeMode ImeMode {
245 if (ime_mode != value) {
248 if (ImeModeChanged != null) {
249 ImeModeChanged(this, EventArgs.Empty);
256 [DefaultValue(ContentAlignment.MiddleCenter)]
257 [MWFDescription("Alignment for button text"), MWFCategory("Appearance")]
258 public virtual ContentAlignment TextAlign {
260 return text_alignment;
264 if (text_alignment != value) {
265 text_alignment = value;
266 switch(text_alignment) {
267 case ContentAlignment.TopLeft: {
268 text_format.Alignment=StringAlignment.Near;
269 text_format.LineAlignment=StringAlignment.Near;
273 case ContentAlignment.TopCenter: {
274 text_format.Alignment=StringAlignment.Center;
275 text_format.LineAlignment=StringAlignment.Near;
279 case ContentAlignment.TopRight: {
280 text_format.Alignment=StringAlignment.Far;
281 text_format.LineAlignment=StringAlignment.Near;
285 case ContentAlignment.MiddleLeft: {
286 text_format.Alignment=StringAlignment.Near;
287 text_format.LineAlignment=StringAlignment.Center;
291 case ContentAlignment.MiddleCenter: {
292 text_format.Alignment=StringAlignment.Center;
293 text_format.LineAlignment=StringAlignment.Center;
297 case ContentAlignment.MiddleRight: {
298 text_format.Alignment=StringAlignment.Far;
299 text_format.LineAlignment=StringAlignment.Center;
303 case ContentAlignment.BottomLeft: {
304 text_format.Alignment=StringAlignment.Near;
305 text_format.LineAlignment=StringAlignment.Far;
309 case ContentAlignment.BottomCenter: {
310 text_format.Alignment=StringAlignment.Center;
311 text_format.LineAlignment=StringAlignment.Far;
315 case ContentAlignment.BottomRight: {
316 text_format.Alignment=StringAlignment.Far;
317 text_format.LineAlignment=StringAlignment.Far;
326 #endregion // Public Instance Properties
328 #region Protected Instance Properties
329 protected override CreateParams CreateParams {
333 cp=base.CreateParams;
335 cp.Style=(int)(WindowStyles.WS_VISIBLE | WindowStyles.WS_CHILD | WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_CLIPCHILDREN);
341 protected override ImeMode DefaultImeMode {
343 return ImeMode.Inherit;
347 protected override Size DefaultSize {
349 return ThemeEngine.Current.ButtonBaseDefaultSize;
353 protected bool IsDefault {
359 if (is_default != value) {
365 #endregion // Public Instance Properties
367 #region Protected Instance Methods
368 protected override AccessibleObject CreateAccessibilityInstance() {
370 ao = base.CreateAccessibilityInstance();
371 ao.description = "Button";
372 ao.role = AccessibleRole.PushButton;
377 protected override void Dispose(bool Disposing) {
378 base.Dispose(Disposing);
381 protected override void OnEnabledChanged(EventArgs e) {
383 base.OnEnabledChanged(e);
386 protected override void OnGotFocus(EventArgs e) {
392 protected override void OnKeyDown(KeyEventArgs kevent) {
393 if (is_enabled && (kevent.KeyData == Keys.Space)) {
394 enter_state = is_entered;
396 OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 2, 2, 0));
399 base.OnKeyDown(kevent);
402 protected override void OnKeyUp(KeyEventArgs kevent) {
403 if (is_enabled && (kevent.KeyData == Keys.Space)) {
404 OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 2, 2, 0));
405 is_entered = enter_state;
408 base.OnKeyUp(kevent);
411 protected override void OnLostFocus(EventArgs e) {
417 protected override void OnMouseDown(MouseEventArgs mevent) {
418 if (is_enabled && (mevent.Button == MouseButtons.Left)) {
424 base.OnMouseDown(mevent);
427 protected override void OnMouseEnter(EventArgs e) {
431 base.OnMouseEnter(e);
434 protected override void OnMouseLeave(EventArgs e) {
438 base.OnMouseLeave(e);
441 protected override void OnMouseMove(MouseEventArgs mevent) {
445 if (mevent.X>=0 && mevent.Y>=0 && mevent.X<this.client_size.Width && mevent.Y<=this.client_size.Height) {
449 // If the button was pressed and we leave, release the button press and vice versa
450 if (this.Capture && (inside != is_pressed)) {
455 if (is_entered != inside) {
464 base.OnMouseMove(mevent);
467 protected override void OnMouseUp(MouseEventArgs mevent) {
468 if (this.Capture && mevent.Button == MouseButtons.Left) {
469 this.Capture = false;
473 } else if ((this.flat_style == FlatStyle.Flat) || (this.flat_style == FlatStyle.Popup)) {
477 if (mevent.X>=0 && mevent.Y>=0 && mevent.X<this.client_size.Width && mevent.Y<=this.client_size.Height) {
478 OnClick(EventArgs.Empty);
481 base.OnMouseUp(mevent);
484 protected override void OnPaint(PaintEventArgs pevent) {
486 base.OnPaint (pevent);
489 protected override void OnParentChanged(EventArgs e) {
490 base.OnParentChanged(e);
493 protected override void OnTextChanged(EventArgs e) {
495 base.OnTextChanged(e);
498 protected override void OnVisibleChanged(EventArgs e) {
504 base.OnVisibleChanged(e);
507 protected void ResetFlagsandPaint() {
508 // Nothing to do; MS internal
509 // Should we do Redraw (); ?
512 protected override void WndProc(ref Message m) {
514 case Msg.WM_LBUTTONDBLCLK: {
519 case Msg.WM_MBUTTONDBLCLK: {
524 case Msg.WM_RBUTTONDBLCLK: {
529 base.WndProc (ref m);
531 #endregion // Public Instance Properties
534 #region Internal Methods
535 private void PerformClick() {
536 OnClick(EventArgs.Empty);
538 #endregion // Internal Methods
542 [EditorBrowsable (EditorBrowsableState.Never)]
543 public new event EventHandler ImeModeChanged;