diff options
Diffstat (limited to 'SparkleShare/Windows/UserInterface/NotifyIcon.cs')
-rw-r--r-- | SparkleShare/Windows/UserInterface/NotifyIcon.cs | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/SparkleShare/Windows/UserInterface/NotifyIcon.cs b/SparkleShare/Windows/UserInterface/NotifyIcon.cs new file mode 100644 index 0000000..f123511 --- /dev/null +++ b/SparkleShare/Windows/UserInterface/NotifyIcon.cs @@ -0,0 +1,188 @@ +// SparkleShare, a collaboration and sharing tool. +// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + + +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Markup; + +using Drawing = System.Drawing; +using Forms = System.Windows.Forms; + +namespace SparkleShare { + + [ContentProperty("Text")] + [DefaultEvent("MouseDoubleClick")] + public class NotifyIcon : UIElement, IAddChild { + + [DllImport("user32.dll", EntryPoint = "DestroyIcon")] + static extern bool DestroyIcon(IntPtr h_icon); + + public Drawing.Bitmap Icon { + set { + Notification.Icon = GetIconFromBitmap(value); + } + } + + public string Text { + get { + return (string) GetValue(TextProperty); + } + set { + var text = value; + + if(!string.IsNullOrEmpty(HeaderText)) + text = HeaderText + "\n" + text; + + SetValue(TextProperty, text); + } + } + + public ContextMenu ContextMenu { + get; + set; + } + + public string HeaderText { + get; + set; + } + + private Forms.NotifyIcon Notification { + get; + set; + } + + public readonly RoutedEvent MouseClickEvent = EventManager.RegisterRoutedEvent( + "MouseClick", RoutingStrategy.Bubble, typeof(MouseButtonEventHandler), typeof(NotifyIcon)); + + public readonly RoutedEvent MouseDoubleClickEvent = EventManager.RegisterRoutedEvent( + "MouseDoubleClick", RoutingStrategy.Bubble, typeof(MouseButtonEventHandler), typeof(NotifyIcon)); + + public readonly DependencyProperty TextProperty = DependencyProperty.Register( + "Text", typeof(string), typeof(NotifyIcon), new PropertyMetadata(OnTextChanged)); + + public NotifyIcon() { + VisibilityProperty.OverrideMetadata(typeof(NotifyIcon), new PropertyMetadata(OnVisibilityChanged)); + + Notification = new Forms.NotifyIcon { + Text = Text, + Visible = true, + ContextMenu = new Forms.ContextMenu() + }; + Notification.MouseDown += OnMouseDown; + Notification.MouseUp += OnMouseUp; + Notification.MouseClick += OnMouseClick; + Notification.MouseDoubleClick += OnMouseDoubleClick; + } + + public void ShowBalloonTip(string title, string subtext, string image_path) { + // TODO: + // - Use the image pointed to by image_path + // - Find a way to use the prettier (Win7?) balloons + Notification.ShowBalloonTip(5 * 1000, title, subtext, Forms.ToolTipIcon.Info); + } + + public void Dispose() { + Notification.Dispose(); + } + + + void IAddChild.AddChild(object value) { + throw new InvalidOperationException(); + } + + void IAddChild.AddText(string text) { + if(text == null) + throw new ArgumentNullException(); + + Text = text; + } + + private static MouseButtonEventArgs CreateMouseButtonEventArgs(RoutedEvent handler, Forms.MouseButtons button) { + MouseButton mouse_button; + + if(button == Forms.MouseButtons.Left) { + mouse_button = MouseButton.Left; + + } else if(button == Forms.MouseButtons.Right) { + mouse_button = MouseButton.Right; + + } else if(button == Forms.MouseButtons.Middle) { + mouse_button = MouseButton.Middle; + + } else if(button == Forms.MouseButtons.XButton1) { + mouse_button = MouseButton.XButton1; + + } else if(button == Forms.MouseButtons.XButton2) { + mouse_button = MouseButton.XButton2; + + } else { + throw new InvalidOperationException(); + } + + return new MouseButtonEventArgs(InputManager.Current.PrimaryMouseDevice, 0, mouse_button) { + RoutedEvent = handler + }; + } + + private void OnVisibilityChanged(DependencyObject target, DependencyPropertyChangedEventArgs args) { + NotifyIcon control = (NotifyIcon) target; + control.Notification.Visible = (control.Visibility == Visibility.Visible); + } + + private void OnMouseDown(object sender, Forms.MouseEventArgs args) { + RaiseEvent(CreateMouseButtonEventArgs(MouseDownEvent, args.Button)); + } + + private void OnMouseClick(object sender, Forms.MouseEventArgs args) { + RaiseEvent(CreateMouseButtonEventArgs(MouseClickEvent, args.Button)); + } + + private void OnMouseDoubleClick(object sender, Forms.MouseEventArgs args) { + RaiseEvent(CreateMouseButtonEventArgs(MouseDoubleClickEvent, args.Button)); + } + + private void OnMouseUp(object sender, Forms.MouseEventArgs args) { + + if(args.Button == Forms.MouseButtons.Right) { + + ContextMenu.IsOpen = true; + ContextMenu.StaysOpen = false; + } + + RaiseEvent(CreateMouseButtonEventArgs(MouseUpEvent, args.Button)); + } + + private static void OnTextChanged(DependencyObject target, DependencyPropertyChangedEventArgs args) { + NotifyIcon control = (NotifyIcon) target; + control.Notification.Text = control.Text; + } + + + private static Drawing.Icon GetIconFromBitmap(Drawing.Bitmap bitmap) { + IntPtr unmanaged_icon = bitmap.GetHicon(); + Drawing.Icon icon = (Drawing.Icon) Drawing.Icon.FromHandle(unmanaged_icon).Clone(); + DestroyIcon(unmanaged_icon); + + return icon; + } + } +} |