ButtonBase.cs, ListView.cs, NotifyIcon.cs, PictureBox.cs, ToolBar.cs, TreeView.cs...
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / NotifyIcon.cs
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:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
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.
19 //
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
21 //
22 // Authors:
23 //      Peter Bartok    pbartok@novell.com
24 //
25 //
26
27 // NOT COMPLETE
28
29 using System;
30 using System.ComponentModel;
31 using System.ComponentModel.Design;
32 using System.Drawing;
33
34 namespace System.Windows.Forms {
35         [DefaultProperty("Text")]
36         [DefaultEvent("MouseDown")]
37         [Designer ("System.Windows.Forms.Design.NotifyIconDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
38         [ToolboxItemFilter("System.Windows.Forms", ToolboxItemFilterType.Allow)]
39         public sealed class NotifyIcon : System.ComponentModel.Component {
40                 #region Local Variables
41                 private ContextMenu             context_menu;
42                 private Icon                    icon;
43                 private Bitmap                  icon_bitmap;
44                 private string                  text;
45                 private bool                    visible;
46                 private NotifyIconWindow        window;
47                 private bool                    systray_active;
48                 private ToolTip                 tooltip;
49                 #endregion      // Local Variables
50
51                 #region NotifyIconWindow Class
52                 internal class NotifyIconWindow : Control {
53                         NotifyIcon      owner;
54                         Rectangle       rect;
55
56                         public NotifyIconWindow(NotifyIcon owner) {
57                                 this.owner = owner;
58                                 is_visible = false;
59                                 rect = new Rectangle(0, 0, 1, 1);
60
61                                 CreateControl();
62
63                                 Paint += new PaintEventHandler(HandlePaint);
64                                 SizeChanged += new EventHandler(HandleSizeChanged);
65
66                                 // Events that need to be sent to our parent
67                                 Click += new EventHandler(HandleClick);
68                                 DoubleClick += new EventHandler(HandleDoubleClick);
69                                 MouseDown +=new MouseEventHandler(HandleMouseDown);
70                                 MouseUp +=new MouseEventHandler(HandleMouseUp);
71                                 MouseMove +=new MouseEventHandler(HandleMouseMove);
72                                 ContextMenu = owner.context_menu;
73                         }
74
75                         protected override CreateParams CreateParams {
76                                 get {
77                                         CreateParams cp;
78
79                                         cp = base.CreateParams;
80
81                                         cp.Parent = IntPtr.Zero;
82                                         cp.Style = (int)WindowStyles.WS_POPUP;
83                                         cp.Style |= (int)WindowStyles.WS_CLIPSIBLINGS;
84
85                                         cp.ExStyle = (int)(WindowStyles.WS_EX_TOOLWINDOW);
86
87                                         return cp;
88                                 }
89                         }
90
91                         protected override void WndProc(ref Message m) {
92                                 switch((Msg)m.Msg) {
93                                         case Msg.WM_NCPAINT: {
94                                                 PaintEventArgs  paint_event;
95
96                                                 paint_event = XplatUI.PaintEventStart(Handle, false);
97                                                 OnPaint(paint_event);
98                                                 XplatUI.PaintEventEnd(Handle, false);
99                                                 break;
100                                         }
101
102                                         case Msg.WM_USER: {
103                                                 switch ((Msg)m.LParam.ToInt32()) {
104                                                         case Msg.WM_LBUTTONDOWN: {
105                                                                 HandleMouseDown(this, new MouseEventArgs(MouseButtons.Left, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));
106                                                                 return;
107                                                         }
108
109                                                         case Msg.WM_LBUTTONUP: {
110                                                                 HandleMouseUp(this, new MouseEventArgs(MouseButtons.Left, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));
111                                                                 HandleClick(this, EventArgs.Empty);
112                                                                 return;
113                                                         }
114
115                                                         case Msg.WM_LBUTTONDBLCLK: {
116                                                                 HandleDoubleClick(this, EventArgs.Empty);
117                                                                 return;
118                                                         }
119
120                                                         case Msg.WM_MOUSEMOVE: {
121                                                                 HandleMouseMove(this, new MouseEventArgs(MouseButtons.None, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));
122                                                                 return;
123                                                         }
124
125                                                         case Msg.WM_RBUTTONDOWN: {
126                                                                 HandleMouseDown(this, new MouseEventArgs(MouseButtons.Right, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));
127                                                                 return;
128                                                         }
129
130                                                         case Msg.WM_RBUTTONUP: {
131                                                                 HandleMouseUp(this, new MouseEventArgs(MouseButtons.Right, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));
132                                                                 HandleClick(this, EventArgs.Empty);
133                                                                 return;
134                                                         }
135
136                                                         case Msg.WM_RBUTTONDBLCLK: {
137                                                                 HandleDoubleClick(this, EventArgs.Empty);
138                                                                 return;
139                                                         }
140                                                 }
141                                                 return;
142                                         }
143                                 }
144                                 base.WndProc (ref m);
145                         }
146
147                         internal void CalculateIconRect() {
148                                 if (owner != null && owner.icon != null) {
149                                         int             x;
150                                         int             y;
151                                         int             size;
152
153                                         // Icons are always square. Try to center them in the window
154                                         if (ClientRectangle.Width < ClientRectangle.Height) {
155                                                 size = ClientRectangle.Width;
156                                         } else {
157                                                 size = ClientRectangle.Height;
158                                         }
159                                         x = this.ClientRectangle.Width / 2 - size / 2;
160                                         y = this.ClientRectangle.Height / 2 - size / 2;
161                                         rect = new Rectangle(x, y, size, size);
162
163                                         // Force our window to be square
164                                         if (Width != size) {
165                                                 this.Width = size;
166                                         }
167
168                                         if (Height != size) {
169                                                 this.Height = size;
170                                         }
171                                 }
172                         }
173
174                         private void HandlePaint(object sender, PaintEventArgs e) {
175                                 if (owner.icon != null) {
176                                         e.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(SystemColors.Window), rect);
177                                         e.Graphics.DrawImage(owner.icon_bitmap, rect);
178
179                                 }
180                         }
181
182                         private void HandleSizeChanged(object sender, EventArgs e) {
183                                 CalculateIconRect();
184                         }
185
186                         private void HandleClick(object sender, EventArgs e) {
187                                 if (owner.Click != null) {
188                                         owner.Click(owner, e);
189                                 }
190                         }
191
192                         private void HandleDoubleClick(object sender, EventArgs e) {
193                                 if (owner.DoubleClick != null) {
194                                         owner.DoubleClick(owner, e);
195                                 }
196                         }
197
198                         private void HandleMouseDown(object sender, MouseEventArgs e) {
199                                 if (owner.MouseDown != null) {
200                                         owner.MouseDown(owner, e);
201                                 }
202                         }
203
204                         private void HandleMouseUp(object sender, MouseEventArgs e) {
205                                 if (owner.context_menu != null) {
206                                         owner.context_menu.Show(this, new Point(e.X, e.Y));
207                                 }
208
209                                 if (owner.MouseUp != null) {
210                                         owner.MouseUp(owner, e);
211                                 }
212                         }
213
214                         private void HandleMouseMove(object sender, MouseEventArgs e) {
215                                 if (owner.MouseMove != null) {
216                                         owner.MouseMove(owner, e);
217                                 }
218                         }
219                 }
220                 #endregion      // NotifyIconWindow Class
221
222                 #region Public Constructors
223                 public NotifyIcon() {
224                         window = new NotifyIconWindow(this);
225                         systray_active = false;
226                 }
227
228                 public NotifyIcon(System.ComponentModel.IContainer container) : this() {
229                 }
230                 #endregion      // Public Constructors
231
232                 #region Private Methods
233                 private void ShowSystray(bool property_changed) {
234                         if (property_changed) {
235                                 window.CalculateIconRect();
236                         }
237
238                         if (systray_active) {
239                                 if (property_changed) {
240                                         UpdateSystray();
241                                 }
242                                 return;
243                         }
244
245                         if (icon == null) {
246                                 return;
247                         }
248
249                         icon_bitmap = icon.ToBitmap();
250
251                         systray_active = true;
252                         XplatUI.SystrayAdd(window.Handle, text, icon, out tooltip);
253                 }
254
255                 private void HideSystray() {
256                         if (!systray_active) {
257                                 return;
258                         }
259
260                         systray_active = false;
261                         XplatUI.SystrayRemove(window.Handle, ref tooltip);
262                 }
263
264                 private void UpdateSystray() {
265                         if (icon_bitmap != null) {
266                                 icon_bitmap.Dispose();
267                         }
268
269                         if (icon != null) {
270                                 icon_bitmap = icon.ToBitmap();
271                         }
272
273                         XplatUI.SystrayChange(window.Handle, text, icon, ref tooltip);
274                         window.Invalidate();
275                 }
276                 #endregion      // Private Methods
277
278                 #region Public Instance Properties
279                 [DefaultValue(null)]
280                 public ContextMenu ContextMenu {
281                         get {
282                                 return context_menu;
283                         }
284
285                         set {
286                                 if (context_menu != value) {
287                                         context_menu = value;
288                                         window.ContextMenu = value;
289                                 }
290                         }
291                 }
292
293                 [Localizable(true)]
294                 [DefaultValue(null)]
295                 public Icon Icon {
296                         get {
297                                 return icon;
298                         }
299
300                         set {
301                                 if (icon != value) {
302                                         icon = value;
303                                         ShowSystray(true);
304                                 }
305                         }
306                 }
307
308                 [Localizable(true)]
309                 public string Text {
310                         get {
311                                 return text;
312                         }
313
314                         set {
315                                 if (text != value) {
316                                         if (value.Length >= 64) {
317                                                 throw new ArgumentException("ToolTip length must be less than 64 characters long", "Text");
318                                         }
319                                         text = value;
320                                         if (text == string.Empty && icon == null) {
321                                                 HideSystray();
322                                         } else {
323                                                 ShowSystray(true);
324                                         }
325                                 }
326                         }
327                 }
328
329                 [Localizable(true)]
330                 [DefaultValue(false)]
331                 public bool Visible {
332                         get {
333                                 return visible;
334                         }
335
336                         set {
337                                 if (visible != value) {
338                                         visible = value;
339
340                                         // Let our control know, too
341                                         window.is_visible = value;
342
343                                         if (visible) {
344                                                 ShowSystray(false);
345                                         } else {
346                                                 HideSystray();
347                                         }
348                                 }
349                         }
350                 }
351                 #endregion      // Public Instance Properties
352
353                 #region Protected Instance Methods
354                 protected override void Dispose(bool disposing) {
355                         if (icon_bitmap != null) {
356                                 icon_bitmap.Dispose();
357                         }
358
359                         if (disposing)
360                                 icon = null;
361
362                         base.Dispose (disposing);
363                 }
364
365                 #endregion      // Protected Instance Methods
366
367                 #region Events
368                 [Category("Action")]
369                 public event EventHandler       Click;
370
371                 [Category("Action")]
372                 public event EventHandler       DoubleClick;
373
374                 public event MouseEventHandler  MouseDown;
375                 public event MouseEventHandler  MouseMove;
376                 public event MouseEventHandler  MouseUp;
377                 #endregion      // Events
378         }
379 }