VoiceGap

Filling the space between You and Your Apps

Cappuccino, Objective-J, and the Future of Cross-Device HTML5 Apps

I am going to embark upon a multi-post series on Objective-J and it’s use in creating HTML5 in-browser Apps. Objective-J is a programming language developed as part of the Cappuccino web development framework. It borrows most of its language features from the Objective-C syntax and it shares with JavaScript the same relationship that Objective-C has with the C programming language Objective-J adds inheritance and Objective-C style dynamic dispatch. It adds the use of class-based programming to JavaScript.

Cappuccino is an open source application framework for developing applications that look and feel like the a desktop application.  Cappuccino is built on top of standard web technologies like JavaScript, and it implements most of the familiar APIs from GNUstep and Apple’s Cocoa frameworks. Programming in Cappuccino hides complexities of DOM based web technologies like HTML, and CSS. The pain of building complex cross browser applications are abstracted away.

What is Cappuccino really?    Go here to learn more.   Cappuccino is Cocoa for the web. Cocoa is the set of libraries and frameworks used to create iOS applications.  Cocoa relies on Objective-C, a superset of C which adds real object-oriented programming.  Cappuccino relies on Objective-J, a superset of JavaScript which adds real object-oriented programming.

With Cappuccino you can build awesome apps for anybody with a web browser. Cappuccino abstracts away the underlying JavaScript and DOM management.
The code you’ll write will work as is in Firefox, Chrome, Safari and Internet Explorer.

You really should check out the Cappuccino demos!  I should warn you that IE 9 and lower will not provide a good experience.

Moonbase Beta,  Part 1. 

The Cappuccino Application is made up of many parts.  So this first tutorial is just one step above ‘hello word,’ I guess we can call it ‘hello moon.’      You can actually develop completely on your local file system as everything runs inside the browser.   Chrome has a small issue with local files; so I’d recommend FireFox for that; but once deployed Chrome is an excellent runtime environment.

You will need to visit the getting started pages listed above.   A Frameworks subdirectory is needed that houses most of the Cappuccino compiler and runtime engine.   You’ll also need some of your on Resources (images and the like).  Then you need to write your Controller class.  And lastly you need a webpage to hold all of this.    I’m going to start with the web page as it might at least be familiar ground for people versed in traditional  HTML and JavaScript.


http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7, chrome=1" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
		<link href="Resources/icon.png" rel="apple-touch-icon" />
		<link href="Resources/default.png" rel="apple-touch-startup-image" />

MoonBaseBeta

<script type="text/javascript">// <![CDATA[
OBJJ_MAIN_FILE = "main.j";              OBJJ_INCLUDE_PATHS = ["Frameworks/Debug", "Frameworks", "MoonBaseBeta_1138"];
// ]]></script>

<script charset="UTF-8" type="text/javascript" src="Frameworks/Debug/Objective-J/Objective-J.js"></script><script type="text/javascript">// <![CDATA[
objj_msgSend_reset(); // Tag view DOM elements with a "data-cappuccino-view" attribute that contains // the class name of the view that created them. Comment this or set to false to disable.              appkit_tag_dom_elements = true;
// ]]></script></pre>
<style type="text/css"><!--
body{margin:0; padding:0;}              #container {position: absolute; top:50%; left:50%;}              #content {width:800px; text-align:center; margin-left: -400px; height:50px; margin-top:-25px; line-height: 50px;}              #content {font-family: "Helvetica", "Arial", sans-serif; font-size: 18px; color: black; text-shadow: 0px 1px 0px white; }              #loadgraphic {margin-right: 0.2em; margin-bottom:-2px;}
--></style>
<pre></pre>
<div id="cappuccino-body">
<div id="loadingcontainer" style="background-color: #eeeeee; overflow: hidden; width: 100%; height: 100%; position: absolute; top: 0; left: 0;">               <script type="text/javascript">// <![CDATA[
document.write("

<div id='container'>

" +
                                    "<img id='loadgraphic' width='16' height='16' src='Resources/spinner.gif' /> " +
                                    "Loading MoonBase...</div>

");
// ]]></script></div>
</div>
<pre>

The important lines above are were the Objective-J program is loaded…

<script type="text/javascript">// <![CDATA[
OBJJ_MAIN_FILE = "main.j";              OBJJ_INCLUDE_PATHS = ["Frameworks/Debug", "Frameworks", "MoonBaseBeta_1138"];
// ]]></script><script charset="UTF-8" type="text/javascript" src="Frameworks/Debug/Objective-J/Objective-J.js">// <![CDATA[

// ]]></script>

So as you might guess we are going to load the Debug version of Objective J, and look for a local file called ‘main.j’ – now main.j is not at all exciting but it is we need to look at it now to understand the next step (pun!).

//
// main.j
//

@import <Foundation/Foundation.j>
@import <AppKit/AppKit.j>
@import "MoonController.j"

function main(args, namedArgs) {
CPApplicationMain(args, namedArgs);
}

It really doesn’t do much more than setup the Foundation Classes, load the AppKit and most importantly Imports the Controller that really holds most of our code for this tutorial.

@import <Foundation/CPObject.j>
@import <AppKit/CPView.j>
@import <AppKit/CPButton.j>
@import <AppKit/CPWebView.j>

@implementation MoonView : CPImageView
{
}

- (id)initWithFrame:(CGRect)aFrame
{
    self = [super initWithFrame:aFrame];

    if (self)
    {
        [self setImage:[[CPImage alloc] initWithContentsOfFile:@"Resources/space1999.png" size:CGSizeMake(320.0, 425.0)]];
        }

    return self;
}
@end

@implementation AppController : CPObject
{
  var _roidView, _roidImage;
}

- (CPPanel)initInfoWindow
{
    var infoWindow = [[CPPanel alloc] initWithContentRect:CGRectMake(400, 50, 320, 480) styleMask:CPHUDBackgroundWindowMask | CPResizableWindowMask];
    [infoWindow setFloatingPanel:YES];

    var _webView = [[CPWebView alloc] initWithFrame:CGRectMake(20, 0, 270, 370)];

    [_webView loadHTMLString:@"</pre>
<center>
<h3>Moonbase Beta</h3>
</center>
<pre>Moonbase Beta is a funtastic game not exclusively for iPhone and iPod touch and inspired by 'Missle Command.'

The goal of the game is simply to survive.</pre>
<center><img alt="" src="Resources/avail_on_app_store.png" /></center>
<pre>"];

    return infoWindow;
}

- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{

    var rootWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask];
    [rootWindow setBackgroundColor:[CPColor grayColor]];
    [rootWindow orderFront:self];

    var gameWindow = [[CPPanel alloc] initWithContentRect:CGRectMake(50, 50, 324, 482) styleMask:CPHUDBackgroundWindowMask];
    [gameWindow setFloatingPanel:YES];
    [gameWindow setTitle:@"Moonbase Beta"];

    contentView = [gameWindow contentView];

    var moonView = [[MoonView alloc] initWithFrame:CGRectMake(2.0, 1.0, 319.0, 479.0)];

    [contentView addSubview:moonView];

    [gameWindow orderFront:self];

}
@end

MoonbaseBeta Here is a screen shot of just the background.   Hello Moon!! The most important method to pay attention to is applicationDidFinishLaunching it basically loads and initializes everything.

The first thing we see is the creation of the outer window.

    var rootWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask];
    [rootWindow setBackgroundColor:[CPColor grayColor]];
    [rootWindow orderFront:self];

Then we create the gameWindow and give it a title.

    var gameWindow = [[CPPanel alloc] initWithContentRect:CGRectMake(50, 50, 324, 482) styleMask:CPHUDBackgroundWindowMask];
    [gameWindow setFloatingPanel:YES];
    [gameWindow setTitle:@"Moonbase Beta"];

Lastly, we create the contentView and we put our MoonView Object in it. The MoonView is the first Class that we have an @Implementation for in the top of the file. you should notice that the initWithFrame has a definition in the class, and that is where the backfround image is loaded form the Resources.

    contentView = [gameWindow contentView];
    var moonView = [[MoonView alloc] initWithFrame:CGRectMake(2.0, 1.0, 319.0, 479.0)];
    [contentView addSubview:moonView];

Comments are currently closed.