Gorm can work on the custom view, which is designed by the programmer, not the built-in GUI component. Here, I continue my "time machine" application to demonstrate how to do that. The new interface looks like this:
Since I want to use the custom view in Gorm, I have to design the class first. The custom view can inherit from NSView, or NSControl, depending on what kind of functions you want. Actually, NSControl is a subclass of NSView. So I will inherit from NSControl. Click on the small circle of NSResponder to open its subclasses, then do the same thing on NSView and NSControl. Now, you can see that many GUI component inherit from NSControl, ex. NSTextField.
I want my custom view, called "TimeView", inherit from NSControl. Choose "NSControl", then select menu "Classes->Create Subclass...". Double-click to change the name.
You can notice that class "TimeView" also inherits 3 outlets and 7 actions from NSControl. Once the class "TimeView" is created, I can use it as custom view.
Build the interface as below:
Look at the "Attributes" in inspector of CustomView. Choose the class "TimeView".
The "CustomView" becomes "TimeView". That's it !
As I did before, create another class for the "controller". Add one outlet for this "TimeView", and one action for the button. I name the outlet "timeView".
Create an instance of class "Controller". Connect the button to the action "showCurrentTime", and the outlet "timeView" to the custom view "TimeView".
Finally, create the class file for the classes "TimeView" and "Controller". Save this application as "TimeMachine.gorm".
Now, I need to design the interface for the class "TimeView". The class "TimeView" is actually four NSTextField in a NSBox. The reason that I made them in one class is because I can reuse it later on. Classes inherited from NSView will be initialized by calling method -initWithFrame:. Therefore, I only need to rewrite the method -initWithFrame: in the class "TimeView". Here are the files:
TimeView.h:
#import <AppKit/AppKit.h> @interface TimeView : NSControl { NSTextField *labelDate, *labelTime; NSTextField *localDate, *localTime; NSCalendarDate *date; } - (NSCalendarDate *) date; - (void) setDate: (NSCalendarDate *) date; @end
TimeView.m:
#import <AppKit/AppKit.h> #import "TimeView.h" @implementation TimeView - (id) initWithFrame: (NSRect) frame { NSBox *box; self = [super initWithFrame: frame]; box = [[NSBox alloc] initWithFrame: NSMakeRect(0, 0, frame.size.width, frame.size.height)]; [box setBorderType: NSGrooveBorder]; [box setTitlePosition: NSAtTop]; [box setTitle: @"Local Time"]; labelDate = [[NSTextField alloc] initWithFrame: NSMakeRect(10, 45, 35, 20)]; [labelDate setStringValue: @"Date: "]; [labelDate setBezeled: NO]; [labelDate setBackgroundColor: [NSColor windowBackgroundColor]]; [labelDate setEditable: NO]; labelTime = [[NSTextField alloc] initWithFrame: NSMakeRect(10, 15, 35, 20)]; [labelTime setStringValue: @"Time: "]; [labelTime setBezeled: NO]; [labelTime setBackgroundColor: [NSColor windowBackgroundColor]]; [labelTime setEditable: NO]; localDate = [[NSTextField alloc] initWithFrame: NSMakeRect(55, 45, 130, 20)]; localTime = [[NSTextField alloc] initWithFrame: NSMakeRect(55, 15, 130, 20)]; [box addSubview: labelDate]; [box addSubview: labelTime]; [box addSubview: localDate]; [box addSubview: localTime]; RELEASE(labelDate); RELEASE(labelTime); RELEASE(localDate); RELEASE(localTime); [self addSubview: box]; RELEASE(box); return self; } - (NSCalendarDate *) date { return date; } - (void) setDate: (NSCalendarDate *) aDate { ASSIGN(date, aDate); [date setCalendarFormat: @"%a, %b %e, %Y"]; [localDate setStringValue: [date description]]; [date setCalendarFormat: @"%H : %M : %S"]; [localTime setStringValue: [date description]]; } - (void) dealloc { RELEASE(date); [super dealloc]; } @end
When Gorm generates the class files, it contains some default codes in it. Since I don't need any of them, they are safe to be removed. In TimeView.h, I declare four NSTextField for display, and on NSCalendarDate to store the date. I also declare two accessory methods to set and get the date. In the -initWithFrame, one NSBox is set up, and four NSTextField is put into it. And class "TimeView" is a subclass of NSView, I add the NSBox as the subview of the class "TimeView".
Other parts of this application should be very easy. Here are the files:
Controller.h:
#import <AppKit/AppKit.h> #import "TimeView.h" @interface Controller : NSObject { id timeView; } - (void) showCurrentTime: (id)sender; @end
Controller.m:
#import <AppKit/AppKit.h> #import "Controller.h" @implementation Controller - (void) showCurrentTime: (id)sender { /* insert your code here */ NSCalendarDate *date = [NSCalendarDate date]; [timeView setDate: date]; } @end
main.m:
#import <AppKit/AppKit.h> int main(int argc, const char *argv[]) { return NSApplicationMain (argc, argv); }
GNUmakefile:
include $(GNUSTEP_MAKEFILES)/common.make APP_NAME = TimeMachine TimeMachine_HEADERS = Controller.h TimeView.h TimeMachine_OBJC_FILES = main.m Controller.m TimeView.m TimeMachine_RESOURCE_FILES = TimeMachineInfo.plist TimeMachine.gorm TimeMachine_MAIN_MODEL_FILE = TimeMachine.gorm include $(GNUSTEP_MAKEFILES)/application.make
You should notice that I didn't instantiate the class "TimeView" in class "Controller" because when I add an custom view to the window, it is instantiated automatically. I only need to specify the class the custom view should be. On the contrary, I have to instantiate the class "Controller" in Gorm because it is not a GUI component. Without instantiation, I can't connect the "controller" to the "view".