在這裡使用 GNUstep 的繪圖功能來顯示時間.
概念上很簡單, 就是在 TimeView 中再加入個自訂元件, ClockView, 即上圖中黃色的時鐘. 當 TimeView 的時間更新時, 也更新 ClockView.
ClockView.h:
#import <AppKit/AppKit.h> #include <math.h> @interface ClockView : NSView { NSPoint posHour, posMinute; } - (void) setDate: (NSCalendarDate *) aDate; @end
ClockView.m:
#import "ClockView.h" @implementation ClockView - (id) init { self = [super init]; posHour = NSMakePoint(0,0); posMinute = NSMakePoint(0,0); return self; } - (void) drawRect: (NSRect) frame { NSPoint origin = NSMakePoint(frame.size.width/2, frame.size.height/2); NSBezierPath *bp = [NSBezierPath bezierPathWithRect: [self bounds]]; [[NSColor yellowColor] set]; [BP fill]; BP = [NSBezierPath bezierPathWithRect: NSMakeRect(1, 1, frame.size.width-2, frame.size.height-2)]; [[NSColor blackColor] set]; [BP stroke]; BP = [NSBezierPath bezierPath]; [BP setLineWidth: 3]; [BP moveToPoint: origin]; [BP relativeLineToPoint: posHour]; [BP stroke]; [BP setLineWidth: 1]; [BP moveToPoint: origin]; [BP relativeLineToPoint: posMinute]; [BP stroke]; } - (void) setDate: (NSCalendarDate *) date; { int hour = [date hourOfDay]; int minute = [date minuteOfHour]; float hour_x = 40*sin((M_PI*hour/6)+(M_PI*minute/360)); float hour_y = 40*cos((M_PI*hour/6)+(M_PI*minute/360)); float minute_x = 60*sin(M_PI*minute/30); float minute_y = 60*COs(M_PI*minute/30); posHour = NSMakePoint(hour_x, hour_y); posMinute = NSMakePoint(minute_x, minute_y); [self setNeedsDisplay: YES]; } @end
ClockView 繼承自 NSView. 最重要的是 -drawRect:. 每次更新視窗時, 就會從 Superview 一路往下呼叫 -drawRect:. 因此所有要更新的部份都在這裡. NSBezierPath 是 GNUstep 中繪圖的元件. 首先先決定路徑, 設定顏色, 最後會是繪圖. 這裡有些相關的文章 (英文) 可以參考: Introduction to Cocoa Graphics, Part I, Part II.
製做好 ClockView 後, 記得在 TimeView 加入 ClockView, 使其成為 TimeView 的 subview. 並在 TimeView 便新時間時呼叫 ClockView 的 -setDate:, 以更新 ClockView 的內容. 在 ClockView 中, [self setNeedsDisplay: YES]; 會通知 GNUstep 要更新 ClockView. 這時 -drawRect: 便會被呼叫. 這些修改很簡單, 可以自行完成.