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 Novell, Inc.
23 // Peter Bartok pbartok@novell.com
25 // $Log: ButtonBase.cs,v $
26 // Revision 1.15 2004/10/15 13:32:45 ravindra
27 // - Renamed Paint() method to Draw() for clarity. Also, moved
28 // DrawImage() to OnPaint().
30 // Revision 1.14 2004/10/15 13:16:10 ravindra
31 // - Redraw () is not virtual now.
32 // - Added an internal virtual method Paint (), so that
33 // derived classes can do their painting on their own.
34 // - Modified OnPaint () to call Paint ().
36 // Revision 1.13 2004/10/14 06:15:57 ravindra
37 // Redraw () related improvements.
39 // Revision 1.12 2004/10/13 22:32:38 pbartok
40 // - Now Redraws on MouseUp for FlatStyle Flat and Popup
42 // Revision 1.11 2004/10/13 20:12:47 pbartok
43 // - Added the Redraw on Resize that got dropped in the last rev
45 // Revision 1.10 2004/10/05 04:56:11 jackson
46 // Let the base Control handle the buffers, derived classes should not have to CreateBuffers themselves.
48 // Revision 1.9 2004/09/28 18:44:25 pbartok
49 // - Streamlined Theme interfaces:
50 // * Each DrawXXX method for a control now is passed the object for the
51 // control to be drawn in order to allow accessing any state the theme
54 // * ControlPaint methods for the theme now have a CP prefix to avoid
55 // name clashes with the Draw methods for controls
57 // * Every control now retrieves it's DefaultSize from the current theme
59 // Revision 1.8 2004/09/02 22:24:35 pbartok
60 // - Fixed selection of text color
61 // - Fixed handling of resize event; now properly recreates double buffering
63 // - Added missing assignment of TextAlignment
64 // - Added proper default for TextAlignment
66 // Revision 1.7 2004/09/01 02:07:37 pbartok
67 // - Enabled display of strings
69 // Revision 1.6 2004/09/01 01:55:20 pbartok
70 // - Removed the rather odd split between 'needs redraw' and redrawing
71 // - Now handles the events that require regeneration (ambient properties and
74 // Revision 1.5 2004/08/31 18:49:58 pbartok
78 // Revision 1.4 2004/08/30 20:42:10 pbartok
79 // - Made Redraw() and Redraw() virtual
80 // - Improved mouse up/down/move logic to properly track buttons
82 // Revision 1.3 2004/08/23 23:27:44 pbartok
83 // - Finishing touches. Works now, just needs some optimizations.
85 // Revision 1.2 2004/08/21 21:57:41 pbartok
86 // - Added loads of debug output for development
87 // - Fixed typo in method name
89 // Revision 1.1 2004/08/15 21:31:10 pbartok
90 // - First (mostly) working version
97 using System.ComponentModel;
99 using System.Drawing.Text;
101 namespace System.Windows.Forms {
102 public abstract class ButtonBase : Control {
103 #region Local Variables
104 internal FlatStyle flat_style;
105 internal int image_index;
106 internal Image image;
107 internal ImageList image_list;
108 internal ContentAlignment image_alignment;
109 internal ContentAlignment text_alignment;
110 private ImeMode ime_mode;
111 private bool is_default;
112 internal bool has_focus;
113 internal bool is_pressed;
114 internal bool is_entered;
115 internal bool redraw;
116 internal StringFormat text_format;
117 #endregion // Local Variables
119 #region Private Properties and Methods
120 internal ButtonState ButtonState {
122 ButtonState ret = ButtonState.Normal;
125 // Popup style is only followed as long as the mouse isn't "in" the control
127 if (flat_style == FlatStyle.Flat) {
128 ret |= ButtonState.Flat;
131 if (flat_style == FlatStyle.Flat || flat_style == FlatStyle.Popup) {
132 ret |= ButtonState.Flat;
136 if (is_entered && is_pressed) {
137 ret |= ButtonState.Pushed;
140 ret |= ButtonState.Inactive;
141 if ((flat_style == FlatStyle.Flat) || (flat_style == FlatStyle.Popup)) {
142 ret |= ButtonState.Flat;
149 [MonoTODO("Make the FillRectangle use a global brush instead of creating one every time")]
150 internal void Redraw() {
155 // Derived classes should override Draw method and we dont want
156 // to break the control signature, hence this approach.
157 internal virtual void Draw (PaintEventArgs pevent) {
159 ThemeEngine.Current.DrawButtonBase(this.DeviceContext, pevent.ClipRectangle, this);
164 private void RedrawEvent(object sender, System.EventArgs e) {
168 #endregion // Private Properties and Methods
170 #region Public Constructors
171 protected ButtonBase() : base() {
172 flat_style = FlatStyle.Standard;
176 image_alignment = ContentAlignment.MiddleCenter;
177 text_alignment = ContentAlignment.MiddleCenter;
178 ime_mode = ImeMode.Inherit;
184 text_format = new StringFormat();
185 text_format.Alignment = StringAlignment.Center;
186 text_format.LineAlignment = StringAlignment.Center;
187 text_format.HotkeyPrefix = HotkeyPrefix.Show;
189 TextChanged+=new System.EventHandler(RedrawEvent);
190 ForeColorChanged+=new EventHandler(RedrawEvent);
191 BackColorChanged+=new System.EventHandler(RedrawEvent);
192 FontChanged+=new EventHandler(RedrawEvent);
193 SizeChanged+=new EventHandler(RedrawEvent);
195 SetStyle (ControlStyles.ResizeRedraw, true);
197 #endregion // Public Constructors
199 #region Public Instance Properties
200 public FlatStyle FlatStyle {
222 public ContentAlignment ImageAlign {
224 return image_alignment;
228 image_alignment=value;
233 public int ImageIndex {
235 if (image_list==null) {
247 public ImageList ImageList {
253 if (image_list != null) {
254 image_list.Dispose();
262 if (image_list.Images.Count >= image_index) {
263 image_index=image_list.Images.Count-1;
270 public ImeMode ImeMode {
280 public virtual ContentAlignment TextAlign {
282 return text_alignment;
286 if (text_alignment != value) {
287 text_alignment = value;
288 switch(text_alignment) {
289 case ContentAlignment.TopLeft: {
290 text_format.Alignment=StringAlignment.Near;
291 text_format.LineAlignment=StringAlignment.Near;
295 case ContentAlignment.TopCenter: {
296 text_format.Alignment=StringAlignment.Center;
297 text_format.LineAlignment=StringAlignment.Near;
301 case ContentAlignment.TopRight: {
302 text_format.Alignment=StringAlignment.Far;
303 text_format.LineAlignment=StringAlignment.Near;
307 case ContentAlignment.MiddleLeft: {
308 text_format.Alignment=StringAlignment.Near;
309 text_format.LineAlignment=StringAlignment.Center;
313 case ContentAlignment.MiddleCenter: {
314 text_format.Alignment=StringAlignment.Center;
315 text_format.LineAlignment=StringAlignment.Center;
319 case ContentAlignment.MiddleRight: {
320 text_format.Alignment=StringAlignment.Far;
321 text_format.LineAlignment=StringAlignment.Center;
325 case ContentAlignment.BottomLeft: {
326 text_format.Alignment=StringAlignment.Near;
327 text_format.LineAlignment=StringAlignment.Far;
331 case ContentAlignment.BottomCenter: {
332 text_format.Alignment=StringAlignment.Center;
333 text_format.LineAlignment=StringAlignment.Far;
337 case ContentAlignment.BottomRight: {
338 text_format.Alignment=StringAlignment.Far;
339 text_format.LineAlignment=StringAlignment.Far;
348 #endregion // Public Instance Properties
350 #region Protected Instance Properties
351 protected override CreateParams CreateParams {
355 cp=base.CreateParams;
357 cp.Style=(int)WindowStyles.WS_VISIBLE | (int)WindowStyles.WS_CHILD;
359 SetStyle(ControlStyles.UserPaint, true);
360 SetStyle(ControlStyles.AllPaintingInWmPaint, true);
365 protected override ImeMode DefaultImeMode {
367 return ImeMode.Inherit;
371 protected override Size DefaultSize {
373 return ThemeEngine.Current.ButtonBaseDefaultSize;
377 protected bool IsDefault {
383 if (is_default != value) {
389 #endregion // Public Instance Properties
391 #region Protected Instance Methods
392 [MonoTODO("Finish setting properties of the AccessibleObject")]
393 protected override AccessibleObject CreateAccessibilityInstance() {
395 ao=base.CreateAccessibilityInstance();
396 ao.description="Button";
401 protected override void Dispose(bool Disposing) {
402 base.Dispose(Disposing);
405 protected override void OnEnabledChanged(EventArgs e) {
407 base.OnEnabledChanged(e);
410 protected override void OnGotFocus(EventArgs e) {
416 protected override void OnKeyDown(KeyEventArgs kevent) {
417 if (is_enabled && (kevent.KeyData == Keys.Enter || kevent.KeyData == Keys.Space)) {
418 OnClick(EventArgs.Empty);
421 base.OnKeyDown(kevent);
424 protected override void OnKeyUp(KeyEventArgs kevent) {
425 base.OnKeyUp(kevent);
428 protected override void OnLostFocus(EventArgs e) {
434 protected override void OnMouseDown(MouseEventArgs mevent) {
435 if (is_enabled && (mevent.Button == MouseButtons.Left)) {
441 base.OnMouseDown(mevent);
444 protected override void OnMouseEnter(EventArgs e) {
446 if ((this.flat_style == FlatStyle.Flat) || (this.flat_style == FlatStyle.Popup)) {
449 base.OnMouseEnter(e);
452 protected override void OnMouseLeave(EventArgs e) {
454 if ((this.flat_style == FlatStyle.Flat) || (this.flat_style == FlatStyle.Popup)) {
457 base.OnMouseLeave(e);
460 protected override void OnMouseMove(MouseEventArgs mevent) {
464 if (mevent.X>=0 && mevent.Y>=0 && mevent.X<this.client_size.Width && mevent.Y<=this.client_size.Height) {
468 // If the button was pressed and we leave, release the button press and vice versa
469 if (this.Capture && (inside != is_pressed)) {
474 if (is_entered != inside) {
483 base.OnMouseMove(mevent);
486 protected override void OnMouseUp(MouseEventArgs mevent) {
487 if (this.Capture && mevent.Button == MouseButtons.Left) {
488 this.Capture = false;
492 } else if ((this.flat_style == FlatStyle.Flat) || (this.flat_style == FlatStyle.Popup)) {
496 if (mevent.X>=0 && mevent.Y>=0 && mevent.X<this.client_size.Width && mevent.Y<=this.client_size.Height) {
497 OnClick(EventArgs.Empty);
500 base.OnMouseUp(mevent);
503 protected override void OnPaint(PaintEventArgs pevent) {
505 pevent.Graphics.DrawImage(this.ImageBuffer, pevent.ClipRectangle, pevent.ClipRectangle, GraphicsUnit.Pixel);
506 base.OnPaint (pevent);
509 protected override void OnParentChanged(EventArgs e) {
510 base.OnParentChanged(e);
513 protected override void OnTextChanged(EventArgs e) {
515 base.OnTextChanged(e);
518 protected override void OnVisibleChanged(EventArgs e) {
524 base.OnVisibleChanged(e);
527 protected void ResetFlagsandPaint() {
528 // Nothing to do; MS internal
529 // Should we do Redraw (); ?
532 protected override void WndProc(ref Message m) {
535 #endregion // Public Instance Properties