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;
33 namespace System.Windows.Forms {
34 public abstract class ButtonBase : Control {
35 #region Local Variables
36 internal FlatStyle flat_style;
37 internal int image_index;
39 internal ImageList image_list;
40 internal ContentAlignment image_alignment;
41 internal ContentAlignment text_alignment;
42 private bool is_default;
43 internal bool is_pressed;
44 internal bool enter_state;
46 internal StringFormat text_format;
47 #endregion // Local Variables
49 #region Private Properties and Methods
50 internal ButtonState ButtonState {
52 ButtonState ret = ButtonState.Normal;
55 // Popup style is only followed as long as the mouse isn't "in" the control
57 if (flat_style == FlatStyle.Flat) {
58 ret |= ButtonState.Flat;
61 if (flat_style == FlatStyle.Flat || flat_style == FlatStyle.Popup) {
62 ret |= ButtonState.Flat;
66 if (is_entered && is_pressed) {
67 ret |= ButtonState.Pushed;
70 ret |= ButtonState.Inactive;
71 if ((flat_style == FlatStyle.Flat) || (flat_style == FlatStyle.Popup)) {
72 ret |= ButtonState.Flat;
79 [MonoTODO("Make the FillRectangle use a global brush instead of creating one every time")]
80 internal void Redraw() {
85 // Derived classes should override Draw method and we dont want
86 // to break the control signature, hence this approach.
87 internal virtual void Draw (PaintEventArgs pevent) {
89 ThemeEngine.Current.DrawButtonBase(this.DeviceContext, pevent.ClipRectangle, this);
94 internal virtual void HaveDoubleClick() {
98 private void RedrawEvent(object sender, System.EventArgs e) {
102 #endregion // Private Properties and Methods
104 #region Public Constructors
105 protected ButtonBase() : base() {
106 flat_style = FlatStyle.Standard;
110 image_alignment = ContentAlignment.MiddleCenter;
111 text_alignment = ContentAlignment.MiddleCenter;
112 ime_mode = ImeMode.Inherit;
118 text_format = new StringFormat();
119 text_format.Alignment = StringAlignment.Center;
120 text_format.LineAlignment = StringAlignment.Center;
121 text_format.HotkeyPrefix = HotkeyPrefix.Show;
123 TextChanged+=new System.EventHandler(RedrawEvent);
124 ForeColorChanged+=new EventHandler(RedrawEvent);
125 BackColorChanged+=new System.EventHandler(RedrawEvent);
126 FontChanged+=new EventHandler(RedrawEvent);
127 SizeChanged+=new EventHandler(RedrawEvent);
129 SetStyle(ControlStyles.UserPaint, true);
130 SetStyle(ControlStyles.AllPaintingInWmPaint, true);
131 SetStyle(ControlStyles.ResizeRedraw, true);
132 SetStyle(ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, false);
134 #endregion // Public Constructors
136 #region Public Instance Properties
138 [DefaultValue(FlatStyle.Standard)]
139 public FlatStyle FlatStyle {
163 [DefaultValue(ContentAlignment.MiddleCenter)]
164 public ContentAlignment ImageAlign {
166 return image_alignment;
170 image_alignment=value;
177 [Editor("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
178 [TypeConverter(typeof(ImageIndexConverter))]
179 public int ImageIndex {
181 if (image_list==null) {
194 public ImageList ImageList {
200 if (image_list != null) {
201 image_list.Dispose();
209 if (image_list.Images.Count >= image_index) {
210 image_index=image_list.Images.Count-1;
218 [EditorBrowsable (EditorBrowsableState.Never)]
219 public new ImeMode ImeMode {
225 if (ime_mode != value) {
228 if (ImeModeChanged != null) {
229 ImeModeChanged(this, EventArgs.Empty);
236 [DefaultValue(ContentAlignment.MiddleCenter)]
237 public virtual ContentAlignment TextAlign {
239 return text_alignment;
243 if (text_alignment != value) {
244 text_alignment = value;
245 switch(text_alignment) {
246 case ContentAlignment.TopLeft: {
247 text_format.Alignment=StringAlignment.Near;
248 text_format.LineAlignment=StringAlignment.Near;
252 case ContentAlignment.TopCenter: {
253 text_format.Alignment=StringAlignment.Center;
254 text_format.LineAlignment=StringAlignment.Near;
258 case ContentAlignment.TopRight: {
259 text_format.Alignment=StringAlignment.Far;
260 text_format.LineAlignment=StringAlignment.Near;
264 case ContentAlignment.MiddleLeft: {
265 text_format.Alignment=StringAlignment.Near;
266 text_format.LineAlignment=StringAlignment.Center;
270 case ContentAlignment.MiddleCenter: {
271 text_format.Alignment=StringAlignment.Center;
272 text_format.LineAlignment=StringAlignment.Center;
276 case ContentAlignment.MiddleRight: {
277 text_format.Alignment=StringAlignment.Far;
278 text_format.LineAlignment=StringAlignment.Center;
282 case ContentAlignment.BottomLeft: {
283 text_format.Alignment=StringAlignment.Near;
284 text_format.LineAlignment=StringAlignment.Far;
288 case ContentAlignment.BottomCenter: {
289 text_format.Alignment=StringAlignment.Center;
290 text_format.LineAlignment=StringAlignment.Far;
294 case ContentAlignment.BottomRight: {
295 text_format.Alignment=StringAlignment.Far;
296 text_format.LineAlignment=StringAlignment.Far;
305 #endregion // Public Instance Properties
307 #region Protected Instance Properties
308 protected override CreateParams CreateParams {
312 cp=base.CreateParams;
314 cp.Style=(int)(WindowStyles.WS_VISIBLE | WindowStyles.WS_CHILD | WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_CLIPCHILDREN);
320 protected override ImeMode DefaultImeMode {
322 return ImeMode.Inherit;
326 protected override Size DefaultSize {
328 return ThemeEngine.Current.ButtonBaseDefaultSize;
332 protected bool IsDefault {
338 if (is_default != value) {
344 #endregion // Public Instance Properties
346 #region Protected Instance Methods
347 [MonoTODO("Finish setting properties of the AccessibleObject")]
348 protected override AccessibleObject CreateAccessibilityInstance() {
350 ao=base.CreateAccessibilityInstance();
351 ao.description="Button";
356 protected override void Dispose(bool Disposing) {
357 base.Dispose(Disposing);
360 protected override void OnEnabledChanged(EventArgs e) {
362 base.OnEnabledChanged(e);
365 protected override void OnGotFocus(EventArgs e) {
371 protected override void OnKeyDown(KeyEventArgs kevent) {
372 if (is_enabled && (kevent.KeyData == Keys.Space)) {
373 enter_state = is_entered;
375 OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 2, 2, 0));
378 base.OnKeyDown(kevent);
381 protected override void OnKeyUp(KeyEventArgs kevent) {
382 if (is_enabled && (kevent.KeyData == Keys.Space)) {
383 OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 2, 2, 0));
384 is_entered = enter_state;
387 base.OnKeyUp(kevent);
390 protected override void OnLostFocus(EventArgs e) {
396 protected override void OnMouseDown(MouseEventArgs mevent) {
397 if (is_enabled && (mevent.Button == MouseButtons.Left)) {
403 base.OnMouseDown(mevent);
406 protected override void OnMouseEnter(EventArgs e) {
408 if ((this.flat_style == FlatStyle.Flat) || (this.flat_style == FlatStyle.Popup)) {
411 base.OnMouseEnter(e);
414 protected override void OnMouseLeave(EventArgs e) {
416 if ((this.flat_style == FlatStyle.Flat) || (this.flat_style == FlatStyle.Popup)) {
419 base.OnMouseLeave(e);
422 protected override void OnMouseMove(MouseEventArgs mevent) {
426 if (mevent.X>=0 && mevent.Y>=0 && mevent.X<this.client_size.Width && mevent.Y<=this.client_size.Height) {
430 // If the button was pressed and we leave, release the button press and vice versa
431 if (this.Capture && (inside != is_pressed)) {
436 if (is_entered != inside) {
445 base.OnMouseMove(mevent);
448 protected override void OnMouseUp(MouseEventArgs mevent) {
449 if (this.Capture && mevent.Button == MouseButtons.Left) {
450 this.Capture = false;
454 } else if ((this.flat_style == FlatStyle.Flat) || (this.flat_style == FlatStyle.Popup)) {
458 if (mevent.X>=0 && mevent.Y>=0 && mevent.X<this.client_size.Width && mevent.Y<=this.client_size.Height) {
459 OnClick(EventArgs.Empty);
462 base.OnMouseUp(mevent);
465 protected override void OnPaint(PaintEventArgs pevent) {
467 pevent.Graphics.DrawImage(this.ImageBuffer, pevent.ClipRectangle, pevent.ClipRectangle, GraphicsUnit.Pixel);
468 base.OnPaint (pevent);
471 protected override void OnParentChanged(EventArgs e) {
472 base.OnParentChanged(e);
475 protected override void OnTextChanged(EventArgs e) {
477 base.OnTextChanged(e);
480 protected override void OnVisibleChanged(EventArgs e) {
486 base.OnVisibleChanged(e);
489 protected void ResetFlagsandPaint() {
490 // Nothing to do; MS internal
491 // Should we do Redraw (); ?
494 protected override void WndProc(ref Message m) {
496 case Msg.WM_LBUTTONDBLCLK: {
501 case Msg.WM_MBUTTONDBLCLK: {
506 case Msg.WM_RBUTTONDBLCLK: {
511 base.WndProc (ref m);
513 #endregion // Public Instance Properties
517 [EditorBrowsable (EditorBrowsableState.Never)]
518 public new event EventHandler ImeModeChanged;