__defineGetter__ and __defineSetter__ , instead of square brackets, usual points, after all. And the worst thing is that Objective-J methods are not first-class objects !@implementation : @implementation Person: CPObject
{
CPString name @accessors;
}
(id) initWithName: (CPString) aName
{
if (self = [super init])
name = aName;
return self;
}
(Person) personWithName: (CPString) aName
{
return [[Person alloc] initWithName: aName];
}
@end @implementation and @end is a class description. The Person class is inherited from CPObject , the top of the Cappuccino class hierarchy. Then in curly braces are declared the member variables of the class. name is a string member variable for which a getter and a setter are automatically generated (by specifying @accessors ). Objective-J accessors have a nonstandard naming rule setName: name and setName: . This format is worth adhering to, because it relies on the internal mechanisms of Cappuccino.[message object] [object message with parameter: value] [object messageSParameter1: value1 parameter2: value2] ...
Person looks like this:var name = [aPerson name]; [aPerson setName: "Vasya"];
@end keyword. Class methods begin with a plus, class instance methods begin with a minus.alloc method of this class creates an uninitialized object, and then the constructor (init-method) initializes it. Often define class methods that simplify this process, personWithName: is an example of such a method.init . Each constructor must first take care of calling the constructor of the superclass, then initialize and return self . The design error is signaled by returning the nil value (yes, during the creation of Objective-C, exceptions were not yet in vogue, so Cocoa and, as a result, Cappuccino do without them).nil , YES and NO . They are identical to null , true and false , respectively. Cappuccino Coding Style Guidelines recommend using them.@implementation , and not, for example, @class . Especially for the same curious: Objective-C, as a superstructure over C, uses declaration files (* .h from headers) and definition files (* .m from messages), so classes must be declared ( @interface ) and defined ( @implementation ) . In Objective-J, ads are not needed, so only @implementation .capp gen "Twitter Search"
AppController file, in Objective-J it is customary to place the code of each class in the same file. Cappuccino creates one instance of AppController at startup, it must initialize the application and manage its further work.Foundation and AppKit , the two main parts of Cappuccino. Foundation contains classes for business logic, and AppKit is a library of user interface classes.@import <Foundation / Foundation.j> @import <AppKit / AppKit.j>
@import keyword @import specified file. As in C, when you specify the path in angle brackets, the file will be searched for in system folders, when using double quotes, in the current folder.applicationDidFinishLaunching: method is called on all objects immediately after starting the application. The meaningful names of the Cappuccino methods make the code understandable even for those who are not familiar with the framework, so I will give explanations only in non-obvious cases. Cappuccino is unlikely to save you keystrokes, so let at least save them to me. var window = [[CPWindow alloc] initWithContentRect: CGRectMake (100, 100, 250, 70)
styleMask: CPTitledWindowMask],
contentView = [window contentView],
textField = [[CPTextField alloc] initWithFrame: CGRectMake (25, 20, 200, 30)]; CGRectMake(x, y, width, height) describes the rectangle in which the control will be located. The contentView method returns a view of the inner window area.[textField setEditable: YES]; [textField setBezeled: YES];
[textField setTarget: self]; [textField setAction: @selector (didSubmitTextField :)];
@selector used to turn a method into a passed value.[contentView addSubview: textField]; [window makeFirstResponder: textField];
[window center]; [window setTitle: "Twitter Search"]; [window orderFront: self];
didSubmitTextField: method didSubmitTextField: - (void) didSubmitTextField: (CPTextField) textField
{
var searchString = [textField stringValue];
if (! searchString)
return;
[[[SearchWindowController alloc] initWithSearchString: searchString] showWindow: nil];
[textField setStringValue: ""];
[[textField window] makeKeyAndOrderFront: nil];
} SearchWindowController , display its window, empty the text field and push its window forward. Things are easy - to develop a class SearchWindowController .CPWindowController : @implementation SearchWindowController: CPWindowController
{
}
@end - (id) initWithSearchString: (CPString) searchString
{
if (self = [super init]) {
var window = [[CPWindow alloc] initWithContentRect: CGRectMake (10, 30, 300, 400)
styleMask: CPTitledWindowMask | CPClosableWindowMask | CPResizableWindowMask];
[window setTitle: searchString];
[self setWindow: window];
var request = [CPURLRequest requestWithURL: "http://search.twitter.com/search.json?q=" + encodeURIComponent (searchString)];
[CPJSONPConnection sendRequest: request callback: "callback" delegate: self];
}
return self;
} - (void) connection: (CPJSONPConnection) connection didReceiveData: (Object) data
{
var contentView = [[self window] contentView];
if (data.results.length) {
var bounds = [contentView bounds],
collectionView = [[CPCollectionView alloc] initWithFrame: bounds];
[collectionView setAutoresizingMask: CPViewWidthSizable];
[collectionView setMaxNumberOfColumns: 1];
[collectionView setMinItemSize: CGSizeMake (200, 100)];
[collectionView setMaxItemSize: CGSizeMake (10000, 100)];
var itemPrototype = [[CPCollectionViewItem alloc] init];
[itemPrototype setView: [TweetView new]];
[collectionView setItemPrototype: itemPrototype];
[collectionView setContent: data.results];
var scrollView = [[CPScrollView alloc] initWithFrame: bounds];
[scrollView setAutoresizingMask: CPViewWidthSizable | CPViewHeightSizable]
[scrollView setDocumentView: collectionView];
[contentView addSubview: scrollView];
} else {
var label = [CPTextField labelWithTitle: "No tweets"],
boundsSize = [contentView boundsSize];
[label setCenter: CGPointMake (boundsSize.width / 2, boundsSize.height / 2)];
[label setAutoresizingMask: CPViewMinXMargin | CPViewMaxXMargin | CPViewMinYMargin | CPViewMaxYMargin];
[contentView addSubview: label];
}
} CPCollectionView , CPCollectionViewItem and CPScrollView library classes to display tweets. But the TweetView class TweetView have to be defined independently.setAutoresizingMask: method. This method will make you forever curse CSS positioning, unless, of course, you have not done so yet. Positioning controls in Cappuccino is so simple and elegant that even a child can handle it.TweetView : @implementation TweetView: CPView
{
CPImageView imageView;
CPTextField userLabel;
CPTextField tweetLabel;
}
- (void) setRepresentedObject: (id) tweet
{
if (! imageView) {
imageView = [[CPImageView alloc] initWithFrame: CGRectMake (10, 5, 48, 48)];
[self addSubview: imageView];
userLabel = [[CPTextField alloc] initWithFrame: CGRectMake (65, 0, -60, 18)];
[userLabel setAutoresizingMask: CPViewWidthSizable];
[userLabel setFont: [CPFont boldSystemFontOfSize: 12]];
[self addSubview: userLabel];
tweetLabel = [[CPTextField alloc] initWithFrame: CGRectMake (65, 18, -60, 100)];
[tweetLabel setAutoresizingMask: CPViewWidthSizable];
[tweetLabel setLineBreakMode: CPLineBreakByWordWrapping];
[self addSubview: tweetLabel];
}
[imageView setImage: [[CPImage alloc] initWithContentsOfFile: tweet.profile_image_url size: CGSizeMake (48, 48)]];
[userLabel setStringValue: tweet.from_user];
[tweetLabel setStringValue: tweet.text];
}
@end setRepresentedObject: method setRepresentedObject: creates an avatar image and two tags, with a username and a tweet.
Source: https://habr.com/ru/post/114749/
All Articles