Skip to content

Commit

Permalink
Merge pull request #53 from euforic/master
Browse files Browse the repository at this point in the history
Added Native 10.8 Notifications
  • Loading branch information
maccman committed Jul 27, 2012
2 parents ba931d3 + 414df37 commit 4de6ff0
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 20 deletions.
6 changes: 6 additions & 0 deletions MacGap.xcodeproj/project.pbxproj
Expand Up @@ -7,6 +7,7 @@
objects = { objects = {


/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1495814F15C15CCC00E1CFE5 /* Notice.m in Sources */ = {isa = PBXBuildFile; fileRef = 1495814E15C15CCC00E1CFE5 /* Notice.m */; };
88746BEE14CCA435001E160E /* JSEventHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 88746BED14CCA435001E160E /* JSEventHelper.m */; }; 88746BEE14CCA435001E160E /* JSEventHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 88746BED14CCA435001E160E /* JSEventHelper.m */; };
88C0646014BDE10A00E4BCE2 /* Window.m in Sources */ = {isa = PBXBuildFile; fileRef = 88C0645F14BDE10A00E4BCE2 /* Window.m */; }; 88C0646014BDE10A00E4BCE2 /* Window.m in Sources */ = {isa = PBXBuildFile; fileRef = 88C0645F14BDE10A00E4BCE2 /* Window.m */; };
88C0646614BDEC5800E4BCE2 /* Window.xib in Resources */ = {isa = PBXBuildFile; fileRef = 88C0646414BDEC5800E4BCE2 /* Window.xib */; }; 88C0646614BDEC5800E4BCE2 /* Window.xib in Resources */ = {isa = PBXBuildFile; fileRef = 88C0646414BDEC5800E4BCE2 /* Window.xib */; };
Expand Down Expand Up @@ -46,6 +47,8 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */


/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
1495814D15C15CCC00E1CFE5 /* Notice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Notice.h; path = Classes/Commands/Notice.h; sourceTree = "<group>"; };
1495814E15C15CCC00E1CFE5 /* Notice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Notice.m; path = Classes/Commands/Notice.m; sourceTree = "<group>"; };
88746BEC14CCA435001E160E /* JSEventHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSEventHelper.h; path = Classes/JSEventHelper.h; sourceTree = "<group>"; }; 88746BEC14CCA435001E160E /* JSEventHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSEventHelper.h; path = Classes/JSEventHelper.h; sourceTree = "<group>"; };
88746BED14CCA435001E160E /* JSEventHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = JSEventHelper.m; path = Classes/JSEventHelper.m; sourceTree = "<group>"; }; 88746BED14CCA435001E160E /* JSEventHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = JSEventHelper.m; path = Classes/JSEventHelper.m; sourceTree = "<group>"; };
88C0645E14BDE10A00E4BCE2 /* Window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Window.h; path = Classes/Window.h; sourceTree = "<group>"; }; 88C0645E14BDE10A00E4BCE2 /* Window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Window.h; path = Classes/Window.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -122,6 +125,8 @@
FA3250E114BA87DD00BF0781 /* Commands */ = { FA3250E114BA87DD00BF0781 /* Commands */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
1495814D15C15CCC00E1CFE5 /* Notice.h */,
1495814E15C15CCC00E1CFE5 /* Notice.m */,
FA3250CA14BA860800BF0781 /* Dock.h */, FA3250CA14BA860800BF0781 /* Dock.h */,
FA3250CB14BA860800BF0781 /* Dock.m */, FA3250CB14BA860800BF0781 /* Dock.m */,
FA3250BD14BA85E700BF0781 /* Utils.h */, FA3250BD14BA85E700BF0781 /* Utils.h */,
Expand Down Expand Up @@ -289,6 +294,7 @@
88C0646014BDE10A00E4BCE2 /* Window.m in Sources */, 88C0646014BDE10A00E4BCE2 /* Window.m in Sources */,
88C0646D14BDF6A600E4BCE2 /* WindowController.m in Sources */, 88C0646D14BDF6A600E4BCE2 /* WindowController.m in Sources */,
88746BEE14CCA435001E160E /* JSEventHelper.m in Sources */, 88746BEE14CCA435001E160E /* JSEventHelper.m in Sources */,
1495814F15C15CCC00E1CFE5 /* Notice.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
Expand Down
20 changes: 20 additions & 0 deletions MacGap/Classes/Commands/Notice.h
@@ -0,0 +1,20 @@
//
// Notice.h
// MacGap
//
// Created by Christian Sullivan on 7/26/12.
// Copyright (c) 2012 Twitter. All rights reserved.
//

#import <Foundation/Foundation.h>

#define APP_NOTICE_NOTIFICATION @"Notice"

@interface Notice : NSObject <NSUserNotificationCenterDelegate> {

}

- (void) notify:(NSDictionary*)message;

@end

50 changes: 50 additions & 0 deletions MacGap/Classes/Commands/Notice.m
@@ -0,0 +1,50 @@
//
// Notice.m
// MacGap
//
// Created by Christian Sullivan on 7/26/12.
// Copyright (c) 2012 Twitter. All rights reserved.
//

#import "Notice.h"

@implementation Notice

- (void) notify:(NSDictionary *)message {
NSUserNotification *notification = [[NSUserNotification alloc] init];
[notification setTitle:[message valueForKey:@"title"]];
[notification setInformativeText:[message valueForKey:@"content"]];
[notification setDeliveryDate:[NSDate dateWithTimeInterval:0 sinceDate:[NSDate date]]];
[notification setSoundName:NSUserNotificationDefaultSoundName];
NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter];
[center scheduleNotification:notification];
}

#pragma mark WebScripting Protocol

+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
{
if (selector == @selector(notify:))
return NO;

return YES;
}

+ (NSString*) webScriptNameForSelector:(SEL)selector
{
id result = nil;

if (selector == @selector(notify:)) {
result = @"notify";
}

return result;
}

// right now exclude all properties (eg keys)
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
{
return YES;
}

@end
3 changes: 3 additions & 0 deletions MacGap/Classes/WebViewDelegate.h
Expand Up @@ -4,6 +4,7 @@
@class Sound; @class Sound;
@class Dock; @class Dock;
@class Growl; @class Growl;
@class Notice;
@class Path; @class Path;
@class App; @class App;
@class Window; @class Window;
Expand All @@ -14,6 +15,7 @@
Sound* sound; Sound* sound;
Dock* dock; Dock* dock;
Growl* growl; Growl* growl;
Notice* notice;
Path* path; Path* path;
App* app; App* app;
Window* window; Window* window;
Expand All @@ -24,6 +26,7 @@
@property (nonatomic, retain) Sound* sound; @property (nonatomic, retain) Sound* sound;
@property (nonatomic, retain) Dock* dock; @property (nonatomic, retain) Dock* dock;
@property (nonatomic, retain) Growl* growl; @property (nonatomic, retain) Growl* growl;
@property (nonatomic, retain) Notice* notice;
@property (nonatomic, retain) Path* path; @property (nonatomic, retain) Path* path;
@property (nonatomic, retain) App* app; @property (nonatomic, retain) App* app;
@property (nonatomic, retain) Window* window; @property (nonatomic, retain) Window* window;
Expand Down
3 changes: 3 additions & 0 deletions MacGap/Classes/WebViewDelegate.m
Expand Up @@ -2,6 +2,7 @@
#import "Sound.h" #import "Sound.h"
#import "Dock.h" #import "Dock.h"
#import "Growl.h" #import "Growl.h"
#import "Notice.h"
#import "Path.h" #import "Path.h"
#import "App.h" #import "App.h"
#import "Window.h" #import "Window.h"
Expand All @@ -11,6 +12,7 @@ @implementation WebViewDelegate
@synthesize sound; @synthesize sound;
@synthesize dock; @synthesize dock;
@synthesize growl; @synthesize growl;
@synthesize notice;
@synthesize path; @synthesize path;
@synthesize app; @synthesize app;
@synthesize window; @synthesize window;
Expand All @@ -21,6 +23,7 @@ - (void) webView:(WebView*)webView didClearWindowObject:(WebScriptObject*)window
if (self.sound == nil) { self.sound = [Sound new]; } if (self.sound == nil) { self.sound = [Sound new]; }
if (self.dock == nil) { self.dock = [Dock new]; } if (self.dock == nil) { self.dock = [Dock new]; }
if (self.growl == nil) { self.growl = [Growl new]; } if (self.growl == nil) { self.growl = [Growl new]; }
if (self.notice == nil) { self.notice = [Notice new]; }
if (self.path == nil) { self.path = [Path new]; } if (self.path == nil) { self.path = [Path new]; }


if (self.app == nil) { if (self.app == nil) {
Expand Down
48 changes: 28 additions & 20 deletions README.md
@@ -1,18 +1,18 @@
#MacGap #MacGap


The MacGap project aims to provide HTML/JS/CSS developers an Xcode project for developing Native OSX Apps that run in OSX's WebView and take advantage of WebKit technologies. The project also exposes a basic JavaScript API for OS integration, such as display Growl notifications. The MacGap project is extremely lightweight and nimble, a blank application is about 0.3mb. The MacGap project aims to provide HTML/JS/CSS developers an Xcode project for developing Native OSX Apps that run in OSX's WebView and take advantage of WebKit technologies. The project also exposes a basic JavaScript API for OS integration, such as display Growl notifications. The MacGap project is extremely lightweight and nimble, a blank application is about 0.3mb.

##Pre-requisites ##Pre-requisites


MacGap works on OSX 10.6 and 10.5. MacGap works on OSX 10.6 and 10.5.


Generate apps with the [macgap generator](http://github.com/maccman/macgap-rb), no compile necessary. Generate apps with the [macgap generator](http://github.com/maccman/macgap-rb), no compile necessary.


gem install macgap gem install macgap

macgap new myapp macgap new myapp
macgap build myapp macgap build myapp

##API ##API


MacGap exposes an object called `macgap` inside JavaScript. You can use it to alter the Dock icon and display Growl notifications, amongst other things. The API is documented below: MacGap exposes an object called `macgap` inside JavaScript. You can use it to alter the Dock icon and display Growl notifications, amongst other things. The API is documented below:
Expand All @@ -24,22 +24,22 @@ App:


// Activate application (bring to front) // Activate application (bring to front)
macgap.app.activate(); macgap.app.activate();

// Hide application // Hide application
macgap.app.hide(); macgap.app.hide();

// Un-hide application // Un-hide application
macgap.app.unhide(); macgap.app.unhide();


// System bell // System bell
macgap.app.beep(); macgap.app.beep();

// Open URL in default browser // Open URL in default browser
macgap.app.open("http://google.com"); macgap.app.open("http://google.com");

// Launch application // Launch application
macgap.app.launch("TextEdit"); macgap.app.launch("TextEdit");

Window: Window:


// Open a new window // Open a new window
Expand All @@ -50,28 +50,28 @@ Window:


// Move window (Bottom left is x:0 and y:0) // Move window (Bottom left is x:0 and y:0)
macgap.window.move({x:0, y: 200}); macgap.window.move({x:0, y: 200});

Path: Path:

// Path to application // Path to application
macgap.path.application; macgap.path.application;

// Path to application's resources // Path to application's resources
macgap.path.resource; macgap.path.resource;

Dock: Dock:


// Set the Dock's badge // Set the Dock's badge
macgap.dock.badge = "10"; macgap.dock.badge = "10";

Sound: Sound:


// Play a sound // Play a sound
macgap.sound.play("./my/sound.mp3") macgap.sound.play("./my/sound.mp3")

// Play a system sound // Play a system sound
macgap.sound.playSystem("funk"); macgap.sound.playSystem("funk");

Growl: Growl:


// Send a Growl notification // Send a Growl notification
Expand All @@ -80,17 +80,25 @@ Growl:
content: "New Message!" content: "New Message!"
}); });


Notice:

// Send a Native User notification
macgap.notice.notify({
title: "Notify",
content: "New Message!"
});

Events: Events:


//Mac OS X on wake event. //Mac OS X on wake event.
document.addEventListener('wake', function(){console.log('Wake!!')}, true); document.addEventListener('wake', function(){console.log('Wake!!')}, true);

//Mac OS X on sleep event. //Mac OS X on sleep event.
document.addEventListener('sleep', function(){console.log('Sleep!!')}, true); document.addEventListener('sleep', function(){console.log('Sleep!!')}, true);

##Offline Patterns ##Offline Patterns


Desktop apps load immediately and work offline, whilst web apps have the advantage of being easily updated and remotely managed. MacGap gives you the best of both worlds via HTML5's offline APIs. Desktop apps load immediately and work offline, whilst web apps have the advantage of being easily updated and remotely managed. MacGap gives you the best of both worlds via HTML5's offline APIs.


First you can define a refresh tag in `index.html`, which will immediately forward your WebView to a given address. First you can define a refresh tag in `index.html`, which will immediately forward your WebView to a given address.


Expand Down

0 comments on commit 4de6ff0

Please sign in to comment.