implementation added
[mono.git] / mcs / class / System.Windows.Forms / System.Windows.Forms / Button.cs
1 //\r
2 // System.Windows.Forms.Button.cs\r
3 //\r
4 // Author:\r
5 //   stubbed out by Jaak Simm (jaaksimm@firm.ee)\r
6 //        implemented for Gtk+ by Rachel Hestilow (hestilow@ximian.com)\r
7 //      Dennis Hayes (dennish@raytek.com)\r
8 //   WINELib implementation started by John Sohn (jsohn@columbus.rr.com)\r
9 //\r
10 // (C) Ximian, Inc., 2002\r
11 //\r
12 \r
13 using System.Drawing;\r
14 using System.Runtime.InteropServices;\r
15 \r
16 namespace System.Windows.Forms {\r
17 \r
18         /// <summary>\r
19         /// Represents a Windows button control.\r
20         /// </summary>\r
21 \r
22         public class Button : ButtonBase, IButtonControl {\r
23 \r
24                 // private fields\r
25                 DialogResult dialogResult;\r
26                 bool MouseIsOver_;\r
27 \r
28                 // --- Constructor ---\r
29                 public Button() : base()\r
30                 {\r
31                         dialogResult = DialogResult.None;\r
32                         MouseIsOver_ = false;\r
33                         SubClassWndProc_ = true;\r
34                 }\r
35                 \r
36                 // --- Properties ---\r
37                 protected override CreateParams CreateParams {\r
38                         get {\r
39                                 // This is a child control, so it must have a parent for creation\r
40                                 if( Parent != null) {\r
41                                         CreateParams createParams = new CreateParams ();\r
42                                         // CHECKME: here we must not overwrite window\r
43                                         if( window == null) {\r
44                                                 window = new ControlNativeWindow (this);\r
45                                         }\r
46 \r
47                                         createParams.Caption = Text;\r
48                                         createParams.ClassName = "BUTTON";\r
49                                         createParams.X = Left;\r
50                                         createParams.Y = Top;\r
51                                         createParams.Width = Width;\r
52                                         createParams.Height = Height;\r
53                                         createParams.ClassStyle = 0;\r
54                                         createParams.ExStyle = 0;\r
55                                         createParams.Param = 0;\r
56                                         createParams.Parent = Parent.Handle;\r
57                                         createParams.Style = (int) (\r
58                                                 WindowStyles.WS_CHILD | \r
59                                                 WindowStyles.WS_VISIBLE |\r
60                                                 WindowStyles.WS_CLIPSIBLINGS );\r
61                                         if(FlatStyle != FlatStyle.System) {\r
62                                                 createParams.Style |= (int) ButtonStyles.BS_OWNERDRAW;\r
63                                         }\r
64                                         createParams.Style |= (int)sysButtonStyles_;\r
65                                         // CHECKME : this call is commented because (IMHO) Control.CreateHandle suppose to do this\r
66                                         // and this function is CreateParams, not CreateHandle\r
67                                         // window.CreateHandle (createParams);\r
68                                         return createParams;\r
69                                 }\r
70                                 return null;\r
71                         }\r
72                 }\r
73                 \r
74                 // --- IButtonControl property ---\r
75                 public virtual DialogResult DialogResult {\r
76                         get { return dialogResult; }\r
77                         set { dialogResult = value; }\r
78                 }\r
79 \r
80                 // --- IButtonControl method ---\r
81                 [MonoTODO]\r
82                 public virtual void NotifyDefault(bool value) \r
83                 {\r
84                         //FIXME:\r
85                 }\r
86                 \r
87                 [MonoTODO]\r
88                 public void PerformClick() \r
89                 {\r
90                         //FIXME:\r
91                 }\r
92                 \r
93                 // --- Button methods for events ---\r
94                 protected override void OnClick(EventArgs e) \r
95                 {\r
96                         base.OnClick (e);\r
97                 }\r
98                 \r
99                 protected override void OnMouseUp(MouseEventArgs e) \r
100                 {\r
101                         base.OnMouseUp (e);\r
102                 }\r
103                 \r
104                 // --- Button methods ---\r
105                 protected override bool ProcessMnemonic (char charCode) \r
106                 {\r
107                         return base.ProcessMnemonic (charCode);\r
108                 }\r
109 \r
110                 [MonoTODO]\r
111                 public override string ToString ()\r
112                 {\r
113                         return base.ToString();\r
114                 }\r
115 \r
116                 protected override void OnMouseEnter (EventArgs e) {\r
117                         base.OnMouseEnter(e);\r
118                         if( FlatStyle == FlatStyle.Flat || FlatStyle == FlatStyle.Popup) {\r
119                                 Invalidate();\r
120                         }\r
121                 }\r
122     \r
123                 protected override void OnMouseLeave (EventArgs e) {\r
124                         base.OnMouseLeave(e);\r
125                         if( FlatStyle == FlatStyle.Flat || FlatStyle == FlatStyle.Popup) {\r
126                                 Invalidate();\r
127                         }\r
128                 }\r
129 \r
130                 internal void OnDrawItem(DrawItemEventArgs e) {\r
131                         Graphics paintOn = e.Graphics;\r
132                         Rectangle rc = e.Bounds;\r
133                         Rectangle rcImageClip = e.Bounds;\r
134                         rcImageClip.Inflate(-2,-2);\r
135 \r
136                         if( FlatStyle == FlatStyle.Flat) {\r
137                                 if( (e.State & DrawItemState.Selected) != 0) {\r
138                                         SolidBrush sb = new SolidBrush(ControlPaint.Light(SystemColors.Control));\r
139                                         paintOn.FillRectangle(sb, rc);\r
140                                         sb.Dispose();\r
141                                 }\r
142                                 else {\r
143                                         if( mouseIsInside_) {\r
144                                                 SolidBrush sb = new SolidBrush(ControlPaint.Dark(SystemColors.Control));\r
145                                                 paintOn.FillRectangle(sb, rc);\r
146                                                 sb.Dispose();\r
147                                         }\r
148                                         else {\r
149                                                 paintOn.FillRectangle(SystemBrushes.Control, rc);\r
150                                         }\r
151                                 }\r
152 \r
153                                 ControlPaint.DrawBorder(paintOn, rc, SystemColors.ControlText, ButtonBorderStyle.Solid);\r
154                                 rc.Inflate(-1,-1);\r
155 \r
156                                 if( (e.State & DrawItemState.Focus) != 0) {\r
157                                         ControlPaint.DrawBorder(paintOn, rc, SystemColors.ControlText, ButtonBorderStyle.Solid);\r
158                                 }\r
159                                 else {\r
160                                         rcImageClip.Inflate(1,1);\r
161                                 }\r
162                                 rc.Inflate(-3,-3);\r
163                         }\r
164                         else if( FlatStyle == FlatStyle.Popup) {\r
165                                 if( (e.State & DrawItemState.Selected) != 0) {\r
166                                         ControlPaint.DrawBorder(paintOn, rc, SystemColors.ControlText, ButtonBorderStyle.Solid);\r
167                                         rc.Inflate(-1,-1);\r
168                                         ControlPaint.DrawBorder(paintOn, rc, SystemColors.ControlText, ButtonBorderStyle.Solid);\r
169                                         rc.Inflate(-1,-1);\r
170                                 }\r
171                                 else {\r
172                                         if( (e.State & DrawItemState.Focus) != 0) {\r
173                                                 ControlPaint.DrawBorder(paintOn, rc, SystemColors.ControlText, ButtonBorderStyle.Solid);\r
174                                                 rc.Inflate(-1,-1);\r
175                                         }\r
176 \r
177                                         if( mouseIsInside_) {\r
178                                                 Color colorLight = ControlPaint.Light(SystemColors.Control);\r
179                                                 ControlPaint.DrawBorder(paintOn, rc, colorLight, 1, ButtonBorderStyle.Solid,\r
180                                                         colorLight, 1, ButtonBorderStyle.Solid, SystemColors.ControlText, 1, ButtonBorderStyle.Solid,\r
181                                                         SystemColors.ControlText, 1, ButtonBorderStyle.Solid);\r
182                                         }\r
183                                         else {\r
184                                                 ControlPaint.DrawBorder(paintOn, rc, SystemColors.ControlText, ButtonBorderStyle.Solid);\r
185                                         }\r
186                                         rc.Inflate(-2,-2);\r
187                                 }\r
188                                 paintOn.FillRectangle(SystemBrushes.Control, rc);\r
189 \r
190                                 rc.Inflate(-1,-1);\r
191                         }\r
192                         else {\r
193                                 ButtonState     btnState = ButtonState.Normal;\r
194 \r
195                                 if( (e.State & DrawItemState.Selected) != 0) {\r
196                                         btnState = ButtonState.Pushed;\r
197                                 }\r
198 \r
199                                 ControlPaint.DrawButton(paintOn, rc, btnState);\r
200 \r
201                                 rc.Inflate(-2,-2);\r
202                         }\r
203 \r
204                         // Do not place Text and Images on the borders \r
205                         paintOn.Clip = new Region(rcImageClip);\r
206                         if( BackgroundImage != null) {\r
207                                 paintOn.DrawImage(BackgroundImage, e.Bounds.X, e.Bounds.Y, BackgroundImage.Width, BackgroundImage.Height);\r
208                         }\r
209 \r
210                         // Make "Focus" rectangle\r
211                         rc.Inflate(-3,-3);\r
212                         Rectangle       focusRC = rc;\r
213 \r
214                         if(Image != null) {\r
215                                 int X = rc.X;\r
216                                 int Y = rc.Y;\r
217 \r
218                                 if( ImageAlign == ContentAlignment.TopCenter ||\r
219                                         ImageAlign == ContentAlignment.MiddleCenter ||\r
220                                         ImageAlign == ContentAlignment.BottomCenter) {\r
221                                         X += (rc.Width - Image.Width) / 2;\r
222                                 }\r
223                                 else if(ImageAlign == ContentAlignment.TopRight ||\r
224                                         ImageAlign == ContentAlignment.MiddleRight||\r
225                                         ImageAlign == ContentAlignment.BottomRight) {\r
226                                         X += (rc.Width - Image.Width);\r
227                                 }\r
228 \r
229                                 if( ImageAlign == ContentAlignment.BottomCenter ||\r
230                                         ImageAlign == ContentAlignment.BottomLeft ||\r
231                                         ImageAlign == ContentAlignment.BottomRight) {\r
232                                         Y += rc.Height - Image.Height;\r
233                                 }\r
234                                 else if(ImageAlign == ContentAlignment.MiddleCenter ||\r
235                                                 ImageAlign == ContentAlignment.MiddleLeft ||\r
236                                                 ImageAlign == ContentAlignment.MiddleRight) {\r
237                                         Y += (rc.Height - Image.Height) / 2;\r
238                                 }\r
239                                 paintOn.DrawImage(Image, X, Y, Image.Width, Image.Height);\r
240                         }\r
241 \r
242                         if( (e.State & DrawItemState.Selected) != 0) {\r
243                                 // FlatStyle.Flat uses color and not text offset to show state\r
244                                 // FIXME: use SysMetrics to determine offset values ?\r
245                                 if( FlatStyle != FlatStyle.Flat) {\r
246                                         rc.Offset(1,1);\r
247                                 }\r
248                         }\r
249 \r
250                         StringFormat format = new StringFormat();\r
251                         format.Alignment = horizontalAlign_;\r
252                         format.LineAlignment = verticalAlign_;\r
253                         paintOn.DrawString(Text, Font, SystemBrushes.ControlText, rc, format);\r
254 \r
255                         if( (e.State & DrawItemState.Focus) != 0) {\r
256                                 // FIXME: Draw focus rectangle in different colors\r
257                                 ControlPaint.DrawFocusRectangle( paintOn, focusRC);\r
258                         }\r
259                 }\r
260 \r
261                 protected override void WndProc (ref Message m) {\r
262                         switch (m.Msg) {\r
263                                 case Msg.WM_DRAWITEM: {\r
264                                         DRAWITEMSTRUCT dis = new DRAWITEMSTRUCT();\r
265                                         dis = (DRAWITEMSTRUCT)Marshal.PtrToStructure(m.LParam, dis.GetType());\r
266                                         Rectangle       rect = new Rectangle(dis.rcItem.left, dis.rcItem.top, dis.rcItem.right - dis.rcItem.left, dis.rcItem.bottom - dis.rcItem.top);\r
267                                         DrawItemEventArgs args = new DrawItemEventArgs(Graphics.FromHdc(dis.hDC), Font,\r
268                                                 rect, dis.itemID, (DrawItemState)dis.itemState);\r
269                                         OnDrawItem( args);\r
270                                         //Marshal.StructureToPtr(dis, m.LParam, false);\r
271                                         m.Result = (IntPtr)1;\r
272                                 }\r
273                                         break;\r
274                                 default:\r
275                                         base.WndProc (ref m);\r
276                                         break;\r
277                         }\r
278                 }\r
279                 \r
280                 /// --- Button events ---\r
281                 /// commented out, cause it only supports the .NET Framework infrastructure\r
282                 /*\r
283                 [MonoTODO]\r
284                 public new event EventHandler DoubleClick {\r
285                         add {\r
286                                 throw new NotImplementedException ();\r
287                         }\r
288                         remove {\r
289                                 throw new NotImplementedException ();\r
290                         }\r
291                 }\r
292                 */\r
293         }\r
294 }\r