[osx] Implement a proper SparkleStatusIcon class

This commit is contained in:
Hylke Bons 2010-12-17 20:18:22 +01:00
parent 46a46a1e05
commit ccaa219a68
4 changed files with 375 additions and 157 deletions

View file

@ -38,13 +38,7 @@ namespace SparkleShare
SparkleLog Log;
NSWindow window;
NSButton button;
NSButton button2;
WebView web_view;
NSDockTile tile;
int i = 0;
@ -60,11 +54,13 @@ namespace SparkleShare
}
SparkleStatusIcon StatusIcon;
public override void FinishedLaunching (NSObject notification)
{
StatusIcon = new SparkleStatusIcon ();
/* tile = NSApplication.SharedApplication.DockTile;
tile.BadgeLabel = "!";
tile.Display ();
@ -76,148 +72,10 @@ tile.Display ();
// SparkleRepo repo = new SparkleRepo ("/Users/hbons/SparkleShare/SparkleShare-Test");
StatusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (28);
//StatusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (28);
StatusItem.Enabled = true;
StatusItem.Image = NSImage.ImageNamed ("idle.png");
StatusItem.AlternateImage = NSImage.ImageNamed ("idle-active.png");
StatusItem.Image.Size = new SizeF (16 , 16);
StatusItem.AlternateImage.Size = new SizeF (16, 16);
StatusItem.HighlightMode = true;
Menu = new NSMenu ();
Menu.AddItem (new NSMenuItem () { Title="Up to date (102 ᴍʙ)", Enabled = true });
Menu.AddItem (NSMenuItem.SeparatorItem);
Timer timer = new Timer () {
Interval = 60
};
FolderMenuItem = new NSMenuItem () {
Title="SparkleShare", Enabled = true,
Action = new Selector ("ddd")
};
timer.Elapsed += delegate {
FolderMenuItem.InvokeOnMainThread (delegate {
StatusItem.Image = NSImage.ImageNamed ("idle" + i + ".png");
StatusItem.Image.Size = new SizeF (16 , 16);
StatusItem.AlternateImage = NSImage.ImageNamed ("idle" + i + ".png");
StatusItem.AlternateImage.Size = new SizeF (16 , 16);
if (i < 4){
i++;
}else{
// StatusItem.Image = NSImage.ImageNamed ("sparkleshare-idle.png");
i = 0;
}
/*FolderMenuItem.Title+="Z";Menu.Update ();*/});
};
timer.Start ();
FolderMenuItem.Activated += delegate {
Console.WriteLine ("DDDD");
};
FolderMenuItem.Image = NSImage.ImageNamed ("sparkleshare.icns");
FolderMenuItem.Image.Size = new SizeF (16, 16);
Menu.AddItem (FolderMenuItem);
FolderMenuItems = new NSMenuItem [2] {
new NSMenuItem () { Title = "gnome-design (2)" },
new NSMenuItem () { Title = "tango-icons" }
};
foreach (NSMenuItem item in FolderMenuItems) {
item.Image = NSImage.ImageNamed ("NSFolder");
item.Image.Size = new SizeF (16, 16);
Menu.AddItem (item);
};
Log = new SparkleLog ("bla");
Menu.AddItem (NSMenuItem.SeparatorItem);
SyncMenuItem = new NSMenuItem () {
Title = "Add Remote Folder..."
};
SyncMenuItem.Activated += delegate {
};
Menu.AddItem (SyncMenuItem);
Menu.AddItem (NSMenuItem.SeparatorItem);
NotificationsMenuItem = new NSMenuItem () {
Title = "Show Notifications",
State = NSCellStateValue.On
};
NotificationsMenuItem.Activated += delegate {
//StatusItem.Image = NSImage.ImageNamed ("NSComputer");
if (NotificationsMenuItem.State == NSCellStateValue.On)
NotificationsMenuItem.State = NSCellStateValue.Off;
else
NotificationsMenuItem.State = NSCellStateValue.On;
};
Menu.AddItem (NotificationsMenuItem);
Menu.AddItem (NSMenuItem.SeparatorItem);
AboutMenuItem = new NSMenuItem () {
Title = "About"
};
AboutMenuItem.Activated += delegate {
};
Menu.AddItem (AboutMenuItem);
// Menu.AddItem (NSMenuItem.SeparatorItem);
QuitMenuItem = new NSMenuItem () {
Title = "Quit"
};
QuitMenuItem.Activated += delegate {
Environment.Exit (0);
};
//Menu.AddItem (QuitMenuItem);
StatusItem.Menu = Menu;
NSApplication.SharedApplication.ActivateIgnoringOtherApps (true);

View file

@ -17,8 +17,6 @@
using System;
using System.Drawing;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using MonoMac.Foundation;
using MonoMac.AppKit;
using MonoMac.ObjCRuntime;
@ -39,22 +37,22 @@ namespace SparkleShare {
{
LocalPath = path;
bool minimizeBox = true;
bool maximizeBox = false;
SetFrame (new RectangleF (0, 0, 480, 640), true);
StyleMask = (NSWindowStyle)(1 | (1 << 1) | (minimizeBox ? 4 : 1) | (maximizeBox ? 8 : 1));
Center ();
StyleMask = (NSWindowStyle.Closable |
NSWindowStyle.Miniaturizable |
NSWindowStyle.Titled);
MaxSize = new SizeF (480, 640);
MinSize = new SizeF (480, 640);
HasShadow = true;
BackingType = NSBackingStore.Buffered;
Center ();
ContentView.AddSubview (CreateEventLog ());
OpenFolderButton = new NSButton (new RectangleF (16, 12, 120, 31)) {

View file

@ -52,6 +52,7 @@
</Compile>
<Compile Include="Layout.cs" />
<Compile Include="SparkleLog.cs" />
<Compile Include="SparkleStatusIcon.cs" />
</ItemGroup>
<ItemGroup>
<Page Include="MainMenu.xib" />

View file

@ -0,0 +1,361 @@
// SparkleShare, an instant update workflow to Git.
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
//
// 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.Drawing;
using System.Timers;
using MonoMac.Foundation;
using MonoMac.AppKit;
using MonoMac.ObjCRuntime;
namespace SparkleShare {
// The statusicon that stays in the
// user's notification area
public class SparkleStatusIcon : NSObject {
private Timer Animation;
private int FrameNumber;
private string StateText;
private NSStatusItem StatusItem;
private NSMenu Menu;
private NSMenuItem StateMenuItem;
private NSMenuItem FolderMenuItem;
private NSMenuItem [] FolderMenuItems;
private NSMenuItem SyncMenuItem;
private NSMenuItem NotificationsMenuItem;
private NSMenuItem AboutMenuItem;
private NSMenuItem QuitMenuItem;
public string _ (string s)
{
return s;
}
public SparkleStatusIcon () : base ()
{
Animation = CreateAnimation ();
StatusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (28);
SetNormalState ();
CreateMenu ();
/* SparkleShare.Controller.FolderSizeChanged += delegate {
Application.Invoke (delegate {
UpdateMenu ();
});
};
SparkleShare.Controller.FolderListChanged += delegate {
Application.Invoke (delegate {
SetNormalState ();
CreateMenu ();
});
};
SparkleShare.Controller.OnIdle += delegate {
Application.Invoke (delegate {
SetNormalState ();
UpdateMenu ();
});
};
SparkleShare.Controller.OnSyncing += delegate {
Application.Invoke (delegate {
SetAnimationState ();
UpdateMenu ();
});
};
SparkleShare.Controller.OnError += delegate {
Application.Invoke (delegate {
SetNormalState (true);
UpdateMenu ();
});
};
*/
}
// Creates the Animation that handles the syncing animation
private Timer CreateAnimation ()
{
FrameNumber = 0;
Timer Animation = new Timer () {
Interval = 35
};
Animation.Elapsed += delegate {
if (FrameNumber < 4)
FrameNumber++;
else
FrameNumber = 0;
InvokeOnMainThread (delegate {
StatusItem.AlternateImage = NSImage.ImageNamed ("idle" + FrameNumber + ".png");
StatusItem.AlternateImage.Size = new SizeF (16, 16);
StatusItem.Image = NSImage.ImageNamed ("idle" + FrameNumber + ".png");
StatusItem.Image.Size = new SizeF (16, 16);
});
};
return Animation;
}
// Creates the menu that is popped up when the
// user clicks the status icon
public void CreateMenu ()
{
Menu = new NSMenu ();
StateMenuItem = new NSMenuItem () {
Title = StateText
};
Menu.AddItem (StateMenuItem);
Menu.AddItem (NSMenuItem.SeparatorItem);
FolderMenuItem = new NSMenuItem () {
Title = "SparkleShare"
};
FolderMenuItem.Activated += delegate {
// SparkleShare.Controller.OpenSparkleShareFolder ();
};
FolderMenuItem.Image = NSImage.ImageNamed ("sparkleshare.icns");
FolderMenuItem.Image.Size = new SizeF (16, 16);
Menu.AddItem (FolderMenuItem);
FolderMenuItems = new NSMenuItem [2] {
new NSMenuItem () { Title = "gnome-design" },
new NSMenuItem () { Title = "tango-icons" }
};
// if (SparkleShare.Controller.Folders.Count > 0) {
// foreach (string path in SparkleShare.Controller.Folders) {
foreach (NSMenuItem item in FolderMenuItems) {
// if (repo.HasUnsyncedChanges)
// folder_action.IconName = "dialog-error";
item.Image = NSImage.ImageNamed ("NSFolder");
item.Image.Size = new SizeF (16, 16);
item.Activated += delegate {
};
item.Activated += OpenEventLogDelegate (item.Title);
Menu.AddItem (item);
};
// } else {
// TODO: No Remote Folders Yet
// }
Menu.AddItem (NSMenuItem.SeparatorItem);
SyncMenuItem = new NSMenuItem () {
Title = "Add Remote Folder..."
};
// if (SparkleShare.Controller.FirstRun)
// SyncMenuItem.Enabled = false;
SyncMenuItem.Activated += delegate {
// TODO
};
Menu.AddItem (SyncMenuItem);
Menu.AddItem (NSMenuItem.SeparatorItem);
NotificationsMenuItem = new NSMenuItem () {
Title = "Show Notifications",
State = NSCellStateValue.On
};
// if (SparkleShare.Controller.NotificationsEnabled)
// NotificationsMenuItem.State = NSCellStateValue.On;
// else
// NotificationsMenuItem.State = NSCellStateValue.On;
NotificationsMenuItem.Activated += delegate {
// SparkleShare.Controller.ToggleNotifications ();
};
Menu.AddItem (NotificationsMenuItem);
Menu.AddItem (NSMenuItem.SeparatorItem);
AboutMenuItem = new NSMenuItem () {
Title = "About"
};
AboutMenuItem.Activated += delegate {
// TODO
};
Menu.AddItem (AboutMenuItem);
StatusItem.Menu = Menu;
}
// A method reference that makes sure that opening the
// event log for each repository works correctly
private EventHandler OpenEventLogDelegate (string path)
{
return delegate {
SparkleLog log = null; //SparkleUI.OpenLogs.Find (delegate (SparkleLog l) { return l.LocalPath.Equals (path); });
// Check whether the log is already open, create a new one if
//that's not the case or present it to the user if it is
if (log == null) {
log = new SparkleLog (path);
/*log.Hidden += delegate {
SparkleUI.OpenLogs.Remove (log);
log.Destroy ();
};
SparkleUI.OpenLogs.Add (log);*/
}
};
}
public void UpdateMenu ()
{
StateMenuItem.Title = StateText;
}
// The state when there's nothing going on
private void SetNormalState ()
{
SetNormalState (false);
}
// The state when there's nothing going on
private void SetNormalState (bool error)
{
Animation.Stop ();
if (false /* SparkleShare.Controller.Folders.Count == 0 */) {
StateText = _("Welcome to SparkleShare!");
InvokeOnMainThread (delegate {
StatusItem.Image = NSImage.ImageNamed ("idle.png");
StatusItem.Image.Size = new SizeF (16, 16);
StatusItem.AlternateImage = NSImage.ImageNamed ("idle-active.png");
StatusItem.AlternateImage.Size = new SizeF (16, 16);
});
} else {
if (error) {
StateText = _("Not everything is synced");
InvokeOnMainThread (delegate {
//Pixbuf = SparkleUIHelpers.GetIcon ("sparkleshare-syncing-error", 24);
});
} else {
StateText = _("Up to date") + " ("/* + SparkleShare.Controller.FolderSize + ")" */;
InvokeOnMainThread (delegate {
StatusItem.Image = NSImage.ImageNamed ("idle.png");
StatusItem.Image.Size = new SizeF (16, 16);
StatusItem.AlternateImage = NSImage.ImageNamed ("idle-active.png");
StatusItem.AlternateImage.Size = new SizeF (16, 16);
});
}
}
}
// The state when animating
private void SetAnimationState ()
{
StateText = _("Syncing…");
if (!Animation.Enabled)
Animation.Start ();
}
}
}