* ImageList.cs: When the image stream is set pull all the images
[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, (string)null)]
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                         }\r
74 \r
75                         protected override CreateParams CreateParams {\r
76                                 get {\r
77                                         CreateParams cp;\r
78 \r
79                                         cp = base.CreateParams;\r
80 \r
81                                         cp.Parent = IntPtr.Zero;\r
82                                         cp.Style = (int)WindowStyles.WS_POPUP;\r
83                                         cp.Style |= (int)WindowStyles.WS_CLIPSIBLINGS;\r
84 \r
85                                         cp.ExStyle = (int)(WindowStyles.WS_EX_TOOLWINDOW);
86 \r
87                                         return cp;\r
88                                 }\r
89                         }\r
90 \r
91                         protected override void WndProc(ref Message m) {\r
92                                 switch((Msg)m.Msg) {\r
93                                         case Msg.WM_USER: {\r
94                                                 switch ((Msg)m.LParam.ToInt32()) {\r
95                                                         case Msg.WM_LBUTTONDOWN: {\r
96                                                                 HandleMouseDown(this, new MouseEventArgs(MouseButtons.Left, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));\r
97                                                                 return;\r
98                                                         }\r
99 \r
100                                                         case Msg.WM_LBUTTONUP: {\r
101                                                                 HandleMouseUp(this, new MouseEventArgs(MouseButtons.Left, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));\r
102                                                                 HandleClick(this, EventArgs.Empty);\r
103                                                                 return;\r
104                                                         }\r
105 \r
106                                                         case Msg.WM_LBUTTONDBLCLK: {\r
107                                                                 HandleDoubleClick(this, EventArgs.Empty);\r
108                                                                 return;\r
109                                                         }\r
110 \r
111                                                         case Msg.WM_MOUSEMOVE: {\r
112                                                                 HandleMouseMove(this, new MouseEventArgs(MouseButtons.None, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));\r
113                                                                 return;\r
114                                                         }\r
115 \r
116                                                         case Msg.WM_RBUTTONDOWN: {\r
117                                                                 HandleMouseDown(this, new MouseEventArgs(MouseButtons.Right, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));\r
118                                                                 return;\r
119                                                         }\r
120 \r
121                                                         case Msg.WM_RBUTTONUP: {\r
122                                                                 HandleMouseUp(this, new MouseEventArgs(MouseButtons.Right, 1, Control.MousePosition.X, Control.MousePosition.Y, 0));\r
123                                                                 HandleClick(this, EventArgs.Empty);\r
124                                                                 return;\r
125                                                         }\r
126 \r
127                                                         case Msg.WM_RBUTTONDBLCLK: {\r
128                                                                 HandleDoubleClick(this, EventArgs.Empty);\r
129                                                                 return;\r
130                                                         }\r
131                                                 }\r
132                                                 return;\r
133                                         }\r
134                                 }\r
135                                 base.WndProc (ref m);\r
136                         }\r
137 \r
138                         internal void CalculateIconRect() {\r
139                                 if (owner != null && owner.icon != null) {\r
140                                         int             x;
141                                         int             y;
142                                         int             size;\r
143 \r
144                                         // Icons are always square. Try to center them in the window\r
145                                         if (ClientRectangle.Width < ClientRectangle.Height) {\r
146                                                 size = ClientRectangle.Width;\r
147                                         } else {\r
148                                                 size = ClientRectangle.Height;\r
149                                         }\r
150                                         x = this.ClientRectangle.Width / 2 - size / 2;\r
151                                         y = this.ClientRectangle.Height / 2 - size / 2;\r
152                                         rect = new Rectangle(x, y, size, size);\r
153 \r
154                                         // Force our window to be square\r
155                                         if (Width != size) {\r
156                                                 this.Width = size;\r
157                                         }\r
158 \r
159                                         if (Height != size) {\r
160                                                 this.Height = size;\r
161                                         }\r
162                                 }\r
163                         }\r
164 \r
165                         private void HandlePaint(object sender, PaintEventArgs e) {\r
166                                 if (owner.icon != null) {\r
167                                         e.Graphics.DrawImage(owner.icon_bitmap, rect);\r
168 \r
169                                 }\r
170                         }\r
171 \r
172                         private void HandleSizeChanged(object sender, EventArgs e) {\r
173                                 CalculateIconRect();\r
174                         }\r
175 \r
176                         private void HandleClick(object sender, EventArgs e) {\r
177                                 if (owner.Click != null) {\r
178                                         owner.Click(owner, e);\r
179                                 }\r
180                         }\r
181 \r
182                         private void HandleDoubleClick(object sender, EventArgs e) {\r
183                                 if (owner.DoubleClick != null) {\r
184                                         owner.DoubleClick(owner, e);\r
185                                 }\r
186                         }\r
187 \r
188                         private void HandleMouseDown(object sender, MouseEventArgs e) {\r
189                                 if (owner.MouseDown != null) {\r
190                                         owner.MouseDown(owner, e);\r
191                                 }\r
192                         }\r
193
194                         private void HandleMouseUp(object sender, MouseEventArgs e) {\r
195                                 if (owner.context_menu != null) {\r
196                                         owner.context_menu.Show(this, new Point(e.X, e.Y));\r
197                                 }\r
198 \r
199                                 if (owner.MouseUp != null) {\r
200                                         owner.MouseUp(owner, e);\r
201                                 }\r
202                         }\r
203 \r
204                         private void HandleMouseMove(object sender, MouseEventArgs e) {\r
205                                 if (owner.MouseMove != null) {\r
206                                         owner.MouseMove(owner, e);\r
207                                 }\r
208                         }\r
209                 }
210                 #endregion      // NotifyIconWindow Class
211
212                 #region Public Constructors
213                 public NotifyIcon() {
214                         window = new NotifyIconWindow(this);
215                         systray_active = false;
216                 }
217
218                 public NotifyIcon(System.ComponentModel.IContainer container) : this() {
219                 }
220                 #endregion      // Public Constructors
221
222                 #region Private Methods
223                 private void ShowSystray(bool property_changed) {
224                         if (property_changed) {
225                                 window.CalculateIconRect();
226                         }
227
228                         if (systray_active) {
229                                 if (property_changed) {
230                                         UpdateSystray();
231                                 }
232                                 return;
233                         }
234
235                         if (icon != null) {
236                                 icon_bitmap = icon.ToBitmap();
237                         }
238
239                         systray_active = true;
240                         XplatUI.SystrayAdd(window.Handle, text, icon, out tooltip);
241                 }
242
243                 private void HideSystray() {
244                         if (!systray_active) {
245                                 return;
246                         }
247
248                         systray_active = false;
249                         XplatUI.SystrayRemove(window.Handle, ref tooltip);
250                 }
251
252                 private void UpdateSystray() {
253                         if (icon_bitmap != null) {
254                                 icon_bitmap.Dispose();
255                         }
256
257                         if (icon != null) {
258                                 icon_bitmap = icon.ToBitmap();
259                         }
260
261                         XplatUI.SystrayChange(window.Handle, text, icon, ref tooltip);
262                         window.Invalidate();
263                 }
264                 #endregion      // Private Methods
265
266                 #region Public Instance Properties
267                 [DefaultValue(null)]
268                 public ContextMenu ContextMenu {
269                         get {
270                                 return context_menu;
271                         }
272
273                         set {
274                                 if (context_menu != value) {
275                                         context_menu = value;
276                                         window.ContextMenu = value;
277                                 }
278                         }
279                 }
280
281                 [Localizable(true)]
282                 [DefaultValue(null)]
283                 public Icon Icon {
284                         get {
285                                 return icon;
286                         }
287
288                         set {
289                                 if (icon != value) {
290                                         if (icon != null) {
291                                                 icon.Dispose();
292                                         }
293                                         icon = value;
294                                         ShowSystray(true);
295                                 }
296                         }
297                 }
298
299                 [Localizable(true)]
300                 public string Text {
301                         get {
302                                 return text;
303                         }
304
305                         set {
306                                 if (text != value) {
307                                         if (value.Length >= 64) {
308                                                 throw new ArgumentException("ToolTip length must be less than 64 characters long", "Text");
309                                         }
310                                         text = value;
311                                         if (text == string.Empty && icon == null) {
312                                                 HideSystray();
313                                         } else {
314                                                 ShowSystray(true);
315                                         }
316                                 }
317                         }
318                 }
319
320                 [Localizable(true)]
321                 [DefaultValue(false)]
322                 public bool Visible {
323                         get {
324                                 return visible;
325                         }
326
327                         set {
328                                 if (visible != value) {
329                                         visible = value;
330
331                                         // Let our control know, too
332                                         window.is_visible = value;
333
334                                         if (visible) {
335                                                 ShowSystray(false);
336                                         } else {
337                                                 HideSystray();
338                                         }
339                                 }
340                         }
341                 }
342                 #endregion      // Public Instance Properties
343
344                 #region Protected Instance Methods
345                 protected override void Dispose(bool disposing) {\r
346                         if (icon != null) {\r
347                                 icon.Dispose();\r
348                         }\r
349 \r
350                         if (icon_bitmap != null) {\r
351                                 icon_bitmap.Dispose();\r
352                         }\r
353                         base.Dispose (disposing);\r
354                 }\r
355
356                 #endregion      // Protected Instance Methods
357
358                 #region Events
359                 [Category("Action")]
360                 public event EventHandler       Click;
361
362                 [Category("Action")]
363                 public event EventHandler       DoubleClick;
364
365                 public event MouseEventHandler  MouseDown;
366                 public event MouseEventHandler  MouseMove;
367                 public event MouseEventHandler  MouseUp;
368                 #endregion      // Events
369         }
370 }