summaryrefslogtreecommitdiff
path: root/SparkleShare/Windows/UserInterface/NotifyIcon.cs
diff options
context:
space:
mode:
Diffstat (limited to 'SparkleShare/Windows/UserInterface/NotifyIcon.cs')
-rw-r--r--SparkleShare/Windows/UserInterface/NotifyIcon.cs188
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;
+ }
+ }
+}