Brew up a Rich Web Application with Cappuccino

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    7 Favorites

    Brew up a Rich Web Application with Cappuccino - Presentation Transcript

    1. Brew up a Rich Web Application with Cappuccino Howard M. Lewis Ship TWD Consulting hlship@comcast.net 1 © 2009 Howard Lewis Ship
    2. Three 'C's, Two 'P's, One 'N' 2 © 2009 Howard Lewis Ship
    3. Agenda • Why Cappuccino? • Getting Started • Objective-J • Running as a Web App • Window Resizing & Remote Communication • Cappuccino Pitfalls 3 © 2009 Howard Lewis Ship
    4. Why Cappuccino? 4 © 2009 Howard Lewis Ship
    5. 5 © 2009 Howard Lewis Ship
    6. 6 © 2009 Howard Lewis Ship
    7. ❝If you need web applications that offer the same user experience as a desktop app would, then Cappuccino is for you. If you truly believe that the classic web development "components" - the usual HTML/CSS/Javascript horror shop - simply stinks, then you are going to be delighted about Cappuccino, too.❞ Holger Jahn 7 © 2009 Howard Lewis Ship
    8. Getting Started 8 © 2009 Howard Lewis Ship
    9. Download http://cappuccino.org/download/ Click Here 9 © 2009 Howard Lewis Ship
    10. Install Tools sudo ./install-tools 10 © 2009 Howard Lewis Ship
    11. Tools Install • Pre-Requisites • Mac or Linux Helps! • Cygwin for Windows • Ruby & Rake •cd Tools ; sudo ./install-tools • Tools & Frameworks installed to /usr/local/share • Must add /usr/local/share/bin to $PATH 11 © 2009 Howard Lewis Ship
    12. Create Example capp gen example 12 © 2009 Howard Lewis Ship
    13. Generated Files Info.plist Application startup information main.j main() method for application AppController.j Application controller (builds initial UI) index.html Launches application index-debug.html Launches application (debug mode) Rakefile Rake build file Frameworks Copy of /usr/local/share/objj/lib/Frameworks Resources Resources (images, etc.) available to application 13 © 2009 Howard Lewis Ship
    14. Configuration /* * AppController.j * example * * Created by You on July 14, 2009. * Copyright 2009, Your Company All rights reserved. */ • capp config key value Stored in ~/.cappconfig • user.name • user.email • organization.name • organization.email • organization.url • organization.identifier 14 © 2009 Howard Lewis Ship
    15. View Example App 15 © 2009 Howard Lewis Ship
    16. Objective-J 16 © 2009 Howard Lewis Ship
    17. Lineage 17 © 2009 Howard Lewis Ship
    18. Objective-C + = Preprocessor 18 © 2009 Howard Lewis Ship
    19. Objective-J Syntax Java Syntax Objective-J Syntax window.orderFront(); [window orderFront]; icon.moveToXY(100, 200); [icon moveToX:100 Y:200]; method moveToX:Y: Java Syntax Objective-J Syntax new JFrame(); [[CPWindow alloc] init]; new JFrame("Toolbox"); [[CPWindow alloc] initWithTitle:"Toolbox"]; Class name Class method Java Syntax Objective-J Syntax this.setNeedsDisplay(true); [self setNeedsDisplay:YES]; Cheat Sheet: this ➠ self, true ➠ YES, false ➠ NO, null ➠ nil 19 © 2009 Howard Lewis Ship
    20. Defining Classes Base class PageView.j @import <AppKit/CPView.j> @implementation PageView : CPView { CALayer _rootLayer; } // Methods defined here @end Convention: instance variables start with underscore 20 © 2009 Howard Lewis Ship
    21. Defining Methods - for instance method type of parameter + for class method PageView.j - (id)initWithFrame:(CGRect)aFrame { self = [super initWithFrame:aFrame]; if (self) Return type { _rootLayer = [CALayer layer]; [self setWantsLayer:YES]; [self setLayer:_rootLayer]; [_rootLayer setBackgroundColor:[CPColor whiteColor]]; [_rootLayer setNeedsDisplay]; } return self; } 21 © 2009 Howard Lewis Ship
    22. No Namespaces 22 © 2009 Howard Lewis Ship
    23. Cappuccino User Interfaces M ac O nl y UI Object properties and connections + = Controller Class Interface Builder File Running User Interface [CPBundle loadCibNamed:owner:loadDelegate:] Instantiates & connects 23 © 2009 Howard Lewis Ship
    24. Actions and Outlets triggerClicked: AppController @implementation AppController : CPObject { CPWindow theWindow; CPTextField outputField; } … - (void)triggerClicked:(id)sender { [outputField setObjectValue:"You clicked it!"]; } @end 24 © 2009 Howard Lewis Ship
    25. capp gen BasicControls -t NibApplication 25 © 2009 Howard Lewis Ship
    26. 26 © 2009 Howard Lewis Ship
    27. Be 1 N ta 5 ov http://280atlas.com/ 27 © 2009 Howard Lewis Ship
    28. Running as a Web App Using Maven & Jetty 28 © 2009 Howard Lewis Ship
    29. 29 © 2009 Howard Lewis Ship
    30. Creating a Web App • mvn archetype:generate • #18 (basic web application) • Edit pom.xml: <plugins> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <configuration> <requestLog implementation="org.eclipse.jetty.server.NCSARequestLog"> <append>true</append> </requestLog> </configuration> </plugin> </plugins> • capp gen src/main/webapp/app • mvn jetty:run • Open http://localhost:8080/app 30 © 2009 Howard Lewis Ship
    31. Creating a simple calculator 31 © 2009 Howard Lewis Ship
    32. Cappuccino Classes CPObject CPResponder undoManager : CPUndoManager menu : CPMenu nextResponder : CPResponder CPView CPWindow hidden : BOOL fullBridge : BOOL frame : CGRect - addSubview:CPView : void level : int - display : void visible : BOOL contentView : CPView backgroundColor : CPColor hasShadow : BOOL title : CPString CPControl CPPanel 32 © 2009 Howard Lewis Ship
    33. Cappuccino Classes CPControl action : SEL target: id enabled : BOOL highlighted : BOOL objectValue : id floatValue: float doubleValue : double intValue : int - initWithFrame:CGFrame : CPControl CPButton CPTextField title : CPString editable : BOOL secure: BOOL - sizeToFit : void bezeled : BOOL + buttonWithTitle:CPString : CPButton + labelWithTitle:CPString : CPTextField 33 © 2009 Howard Lewis Ship
    34. Adding Controls AppController.j - (void)applicationDidFinishLaunching:(CPNotification)aNotification { var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask], contentView = [theWindow contentView]; _display = [CPTextField labelWithTitle:"(placeholder)"]; [_display setBezeled:YES]; [_display sizeToFit]; [contentView addSubview:_display]; [theWindow orderFront:self]; } 34 © 2009 Howard Lewis Ship
    35. Utility Methods AppController.j - (void)add:(CPView)subview { [_contentView addSubview:subview]; } - (CPButton)makeButton:value at:(CGRect)frame { var button = [[CPButton alloc] initWithFrame:frame]; [button setTitle:value.toString()]; [self add:button]; return button; } 35 © 2009 Howard Lewis Ship
    36. More Controls AppController.j _display = [CPTextField labelWithTitle:"(placeholder)"]; [_display setFrame:CGRectMake(5, 5, 180, 30)] [_display setBezeled:YES]; [self add:_display]; [self makeButton:7 at:CGRectMake(5, 35, 40, 25)]; [self makeButton:8 at:CGRectMake(50, 35, 40, 25)]; [self makeButton:9 at:CGRectMake(95, 35, 40, 25)]; [self makeButton:"*" at:CGRectMake(140, 35, 40, 25)]; [self makeButton:4 at:CGRectMake(5, 65, 40, 25)]; [self makeButton:5 at:CGRectMake(50, 65, 40, 25)]; [self makeButton:6 at:CGRectMake(95, 65, 40, 25)]; [self makeButton:"-" at:CGRectMake(140, 65, 40, 25)]; [self makeButton:1 at:CGRectMake(5, 95, 40, 25)]; [self makeButton:2 at:CGRectMake(50, 95, 40, 25)]; [self makeButton:3 at:CGRectMake(95, 95, 40, 25)]; [self makeButton:"+" at:CGRectMake(140, 95, 40, 25)]; [self makeButton:0 at:CGRectMake(5, 125, 85, 25)]; [self makeButton:"." at:CGRectMake(95, 125, 40, 25)]; [self makeButton:"=" at:CGRectMake(140, 125, 40, 25)]; 36 © 2009 Howard Lewis Ship
    37. Local vars have no type - (CPButton)makeDigit:(int)value at:(CGRect)frame { Should be var CPButton button = [self makeButton:value at:frame action:@selector(digit:)]; [button setTag:value]; return button; } 37 © 2009 Howard Lewis Ship
    38. Local vars have no type - (CPButton)makeDigit:(int)value at:(CGRect)frame { Should be var CPButton button = [self makeButton:value at:frame action:@selector(digit:)]; [button setTag:value]; return button; } Not helpful! 38 © 2009 Howard Lewis Ship
    39. Client Exception — Safari 39 © 2009 Howard Lewis Ship
    40. Client Exception — Safari 40 © 2009 Howard Lewis Ship
    41. Fleshed-Out Calculator AppController.j _display = [CPTextField labelWithTitle:""]; [_display setAlignment:CPRightTextAlignment]; [_display setFrame:CGRectMake(1, 5, 183, 30)] [_display setBezeled:YES]; [self add:_display]; [self makeButton:"C" atX:0 y:0 action:@selector(clear:)]; [self makeButton:"/" atX:3 y:0 action:@selector(div:)]; [self makeButton:"*" atX:3 y:1 action:@selector(mult:)]; [self makeButton:"-" atX:3 y:2 action:@selector(minus:)]; [self makeButton:"+" atX:3 y:3 action:@selector(plus:)]; [self makeDigit:7 atX:0 y:1]; [self makeDigit:8 atX:1 y:1]; [self makeDigit:9 atX:2 y:1]; … [[self makeButton:"=" atX:3 y:4 action:@selector(compute:)] setDefaultButton:YES]; 41 © 2009 Howard Lewis Ship
    42. Utility Methods AppController.j - (CPButton)makeButton:(id)value atX:(int)x y:(int)y action:(SEL)action { var frame = CGRectMake(45 * x + 5, 30 * y + 35, 40, 24); var button = [[CPButton alloc] initWithFrame:frame]; [button setTitle:value.toString()]; [button setTarget:self]; [button setAction:action]; [self add:button]; return button; } - (CPButton)makeDigit:(id)value atX:(int)x y:(int)y { return [self makeButton:value atX:x y:y action:@selector(digit:)]; } 42 © 2009 Howard Lewis Ship
    43. Action Methods @selector(digit:) AppController.j - (void)digit:(CPButton)source { var digit = [source title]; if (_value == "" && digit == "0") return; _value = _sign + _value + digit; _sign = ""; [_display setStringValue:_value]; } - (void)clear:(id)source { [self reset]; } 43 © 2009 Howard Lewis Ship
    44. Nesting Controllers 44 © 2009 Howard Lewis Ship
    45. HUD Panel 45 © 2009 Howard Lewis Ship
    46. Main UI Top level window AppController.j - (void)applicationDidFinishLaunching:(CPNotification)aNotification { var window = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask], contentView = [window contentView]; var button = [CPButton buttonWithTitle:@"Calculator"]; [button setFrameOrigin:CGPointMake(60, 40)]; [contentView addSubview:button]; [button setTarget:self]; [button setAction:@selector(raiseCalculatorPanel:)]; [window orderFront:self]; } 46 © 2009 Howard Lewis Ship
    47. Creating CalcController AppController.j … @import "CalcController.j" @implementation AppController : CPObject { CalcController _calcController; } … - (void)raiseCalculatorPanel:(id)sender { if (_calcController == nil) _calcController = [[CalcController alloc] init]; [_calcController show]; } @end 47 © 2009 Howard Lewis Ship
    48. CalcController UI CalcController.j - (id)init { self = [super init]; _panel = [[CPPanel alloc] initWithContentRect:CGRectMake(20, 30, 184, 184) styleMask:CPHUDBackgroundWindowMask | CPClosableWindowMask]; _contentView = [_panel contentView]; [_panel setTitle:"Calculator"]; _display = [CPTextField labelWithTitle:""]; [_display setAlignment:CPRightTextAlignment]; [_display setFrame:CGRectMake(1, 5, 183, 30)] [_display setBezeled:YES]; [self add:_display]; [self makeButton:"C" atX:0 y:0 action:@selector(clear:)]; … return self; } 48 © 2009 Howard Lewis Ship
    49. Window Resizing & Remote Communication 49 © 2009 Howard Lewis Ship
    50. 50 © 2009 Howard Lewis Ship
    51. Twitter Panel UI TwitterController.j _panel = [[CPPanel alloc] initWithContentRect:CGRectMake(20, 30, 245, 184) styleMask:CPHUDBackgroundWindowMask | CPClosableWindowMask | CPResizableWindowMask]; [_panel setTitle:@"Twitter"]; var label = [CPTextField labelWithTitle:"User:"]; [label setFrame:CGRectMake(3, 7, 50, 24)]; [label setTextColor:[CPColor whiteColor]]; _field = [CPTextField textFieldWithStringValue:"" placeholder:"Twitter User" width:200]; [_field setFrame:CGRectMake(40, 0, 200, 28)]; [_field setTarget:self]; [_field setAction:@selector(startSearch:)]; var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(0, 32, 245, 160)]; [scrollView setAutohidesScrollers:YES]; var content = [_panel contentView]; [content addSubview:label]; [content addSubview:_field]; [content addSubview:scrollView]; 51 © 2009 Howard Lewis Ship
    52. 52 © 2009 Howard Lewis Ship
    53. Autoresize Flags Containing CPView CPViewMinYMargin CPView HeightSizable CPViewMinXMargin CPViewMaxXMargin CPView CPViewWidthSizable CPViewMaxYMargin 53 © 2009 Howard Lewis Ship
    54. Autoresizing TwitterController.j [_panel setTitle:@"Twitter"]; [_panel setMinSize:CGSizeMake(245, 184)]; var label = [CPTextField labelWithTitle:"User:"]; [label setFrame:CGRectMake(3, 7, 50, 24)]; [label setTextColor:[CPColor whiteColor]]; _field = [CPTextField textFieldWithStringValue:"" placeholder:"Twitter User" width:200]; [_field setFrame:CGRectMake(40, 0, 200, 28)]; [_field setTarget:self]; [_field setAction:@selector(startSearch:)]; [_field setAutoresizingMask:CPViewWidthSizable]; var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(0, 32, 245, 160)]; [scrollView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; [scrollView setAutohidesScrollers:YES]; [scrollView setBackgroundColor:[CPColor whiteColor]]; Temporary 54 © 2009 Howard Lewis Ship
    55. 55 © 2009 Howard Lewis Ship
    56. CPCollectionView TwitterController.j var itemPrototype = [[CPCollectionViewItem alloc] init]; [itemPrototype setView:[[TwitView alloc] init]]; _timelineView = [[CPCollectionView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(scrollViewBounds) - 2, 0)]; [_timelineView setItemPrototype:itemPrototype]; [_timelineView setDelegate:self]; [_timelineView setMaxNumberOfColumns:1]; [_timelineView setAutoresizingMask:CPViewWidthSizable]; [_scrollView setDocumentView:_timelineView]; 56 © 2009 Howard Lewis Ship
    57. JSON ➠ Image & Label { "title" : "Mmm - biscuits and gravy, in my hometown, with the woman I love.", … "user" : { "profile_image_url" : "http://a3.twimg.com/profile_images/71386417/scott_davis_2009_normal.jpg", … } } TwitView.j - (void)setRepresentedObject:(JSONObject)obj { if (!_label) { … } [_imageView setImage:[[CPImage alloc] initByReferencingFile:obj.user.profile_image_url size:CPSizeMake(55, 55)]]; [_label setStringValue:obj.text]; } @end 57 © 2009 Howard Lewis Ship
    58. Sending the Search Request Cached file (to avoid authentication) TwitterController.j - (void)startSearch:(id)sender { var url = "twitter/statuses/friends_timeline/" + [_field stringValue] + ".json"; var request = [CPURLRequest requestWithURL:url]; [CPURLConnection connectionWithRequest:request delegate:self]; } Who to notify when data arrives 58 © 2009 Howard Lewis Ship
    59. Handling the Response TwitterController.j - (void)connection:(CPURLConnection)connection didReceiveData:(CPString)data { var timeline = JSON.parse(data); [_timelineView setContent:timeline]; } - (void)connection:(CPURLConnection)connection didFailWithError:(CPString)error { CPLog.error(error); } TwitView.j - (void)setRepresentedObject:(JSONObject)obj { ... } @end 59 © 2009 Howard Lewis Ship
    60. Cappuccino Pitfalls 60 © 2009 Howard Lewis Ship
    61. Documentation 61 © 2009 Howard Lewis Ship
    62. Mac-Centric 62 © 2009 Howard Lewis Ship
    63. Compilation Exceptions 63 © 2009 Howard Lewis Ship
    64. Client-Side Efficiency 64 © 2009 Howard Lewis Ship
    65. Wrap Up 65 © 2009 Howard Lewis Ship
    66. http://github.com/hlship/nfjs-cappuccino 66 © 2009 Howard Lewis Ship
    67. http://cappuccino.org 67 © 2009 Howard Lewis Ship
    68. Image Credits © 2008 nalungaard http://www.flickr.com/photos/nalundgaard/2587677285/ © 2005 Michael Sarver http://www.flickr.com/photos/michaelsarver/44302391/ © 2007 Till Krech http://www.flickr.com/photos/extranoise/487179535/ © 2009 Phill Davison http://www.flickr.com/photos/phill_dvsn/3771462059/ © 2007 Howard Gees http://www.flickr.com/photos/cyberslayer/952153409/ © 2006 Tyler Hawkins http://www.flickr.com/photos/m4m/279364376/ © 2009 Harald http://www.flickr.com/photos/haarald/3227728698/ © 2006 Brittney Bush Bollay http://www.flickr.com/photos/tzofia/247056173/ 68 © 2009 Howard Lewis Ship

    + Howard Lewis ShipHoward Lewis Ship, 4 weeks ago

    custom

    1252 views, 7 favs, 6 embeds more stats

    An overview of the Cappuccino rich client framework more

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 1252
      • 780 on SlideShare
      • 472 from embeds
    • Comments 0
    • Favorites 7
    • Downloads 0
    Most viewed embeds
    • 459 views on http://tapestryjava.blogspot.com
    • 9 views on http://www.nofluffjuststuff.com
    • 1 views on http://127.0.0.1:8795
    • 1 views on http://feeds.feedburner.com
    • 1 views on http://xss.yandex.net

    more

    All embeds
    • 459 views on http://tapestryjava.blogspot.com
    • 9 views on http://www.nofluffjuststuff.com
    • 1 views on http://127.0.0.1:8795
    • 1 views on http://feeds.feedburner.com
    • 1 views on http://xss.yandex.net
    • 1 views on http://www.hanrss.com

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories