Cocoa 应用中根本没有调用 drawRect()
drawRect() is not called at all in Cocoa app
我是编程 OS X Cocoa 应用程序的新手。所以请同情。我想让一个应用程序变得简单,但我已经阻止了自己在应用程序中绘制图像。
此代码应绘制多个图像并在调整大小时或最大化 window 应用程序时更改排列。
#include <Cocoa/Cocoa.h>
#ifndef NSWindowStyleMaskTitled
#define NSWindowStyleMaskTitled NSTitledWindowMask
#define NSWindowStyleMaskClosable NSClosableWindowMask
#define NSWindowStyleMaskMiniaturizable NSMiniaturizableWindowMask
#define NSWindowStyleMaskResizable NSResizableWindowMask
#define NSEventMaskAny NSAnyEventMask
#endif
@interface Window : NSWindow {
NSTimer* mTimer;
}
- (instancetype)init;
- (BOOL) acceptsFirstResponder;
- (BOOL) acceptsFirstMouse: (NSEvent*) pEvent;
- (void) viewDidMoveToWindow;
- (void) drawRect: (NSRect) rect;
- (void) onTimer: (NSTimer*) pTimer;
- (void) getMouseXY: (NSEvent*) pEvent x: (int*) pX y: (int*) pY;
- (void) mouseDown:(NSEvent*)event;
- (void) mouseUp: (NSEvent*) event;
- (void) mouseDragged: (NSEvent*) event;
- (void) rightMouseDown: (NSEvent*) event;
- (void) rightMouseUp: (NSEvent*) event;
- (NSDragOperation) draggingEntered:(id <NSDraggingInfo>)sender;
- (BOOL) performDragOperation:(id <NSDraggingInfo>)sender;
- (void) windowDidResize:(NSNotification*)notification;
- (void) windowDidMiniaturize:(NSNotification*)sender;
- (void) windowDidDeMiniaturize:(NSNotification*)sender;
- (BOOL) windowShouldClose:(id)sender;
@end
@implementation Window
- (instancetype)init {
mTimer = 0;
double sec = 1.0 / 24;
mTimer = [NSTimer timerWithTimeInterval:sec target:self selector:@selector(onTimer:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer: mTimer forMode: (NSString*) kCFRunLoopCommonModes];
[self registerForDraggedTypes:[NSArray arrayWithObjects: NSFilenamesPboardType, nil]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidMiniaturize:) name:NSWindowDidMiniaturizeNotification object:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidDeMiniaturize:) name:NSWindowDidDeminiaturizeNotification object:self];
[super initWithContentRect:NSMakeRect(0, 0, 500, 300) styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable backing:NSBackingStoreBuffered defer:NO];
[self setTitle:@"Hello world"];
[self center];
[self setOpaque:NO];
[self setHasShadow:YES];
//[self setBackgroundColor:[NSColor clearColor]];
[self setBackgroundColor:[NSColor grayColor]];
[self setIsVisible:YES];
return self;
}
- (BOOL) acceptsFirstResponder {
return YES;
}
- (BOOL) acceptsFirstMouse: (NSEvent*) pEvent {
return YES;
}
- (void) viewDidMoveToWindow {
NSWindow* pWindow = [self window];
if (pWindow) {
[pWindow makeFirstResponder: self];
[pWindow setAcceptsMouseMovedEvents: YES];
}
}
- (void) drawRect: (NSRect) rect {
NSLog(@"drawRect %f, %f, %f", rect.origin.x, rect.origin.y, rect.size.width);
}
- (void) onTimer: (NSTimer*) pTimer {
NSRect r;
if (pTimer == mTimer) {
//NSLog(@"mTimer");
}
}
- (void) getMouseXY: (NSEvent*) pEvent x: (int*) pX y: (int*) pY {
NSPoint pt = [pEvent locationInWindow];
*pX = (int) pt.x;
//*pY = mGraphics->Height() - (int) pt.y;
*pY = 555 - (int) pt.y;
NSLog(@"%f , %f", pt.x, pt.y);
}
- (void)mouseDown:(NSEvent*)event {
NSLog(@"mouseDown called");
}
- (void) mouseUp: (NSEvent*) event {
int x, y;
[self getMouseXY:event x:&x y:&y];
}
- (void) mouseDragged: (NSEvent*) event {
int x, y;
[self getMouseXY:event x:&x y:&y];
}
- (void) rightMouseDown: (NSEvent*) event {
int x, y;
[self getMouseXY:event x:&x y:&y];
}
- (void) rightMouseUp: (NSEvent*) event {
int x, y;
[self getMouseXY:event x:&x y:&y];
}
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>) sender {
NSPasteboard *pboard = [sender draggingPasteboard];
return (([pboard.types containsObject:NSFilenamesPboardType]) ? NSDragOperationLink : NSDragOperationNone);
}
- (BOOL)performDragOperation:(id <NSDraggingInfo>) sender {
NSPasteboard *pboard = [sender draggingPasteboard];
if ( [[pboard types] containsObject:NSFilenamesPboardType] ) {
//NSPoint pt = [self convertPoint:[sender draggingLocation] fromView:nil];
for (NSString *path in [pboard propertyListForType:NSFilenamesPboardType]) {
const char* tmp=[path UTF8String];
NSLog(@"%@", path);
//if (mGraphics) {
//mGraphics->OnMouseDrop(pt.x, mGraphics->Height() - pt.y, (char*)tmp);
//break;
//}
}
}
return YES;
}
- (void)windowDidResize:(NSNotification*)notification {
//NSLog(@"Resize");
}
- (void)windowDidMiniaturize:(NSNotification*)notification {
NSLog(@"Minimize");
}
- (void)windowDidDeMiniaturize:(NSNotification*)notification {
NSLog(@"DeMinimize");
}
- (BOOL)windowShouldClose:(id)sender {
[NSApp terminate:sender];
return YES;
}
@end
int main(int argc, char* argv[]) {
[NSApplication sharedApplication];
[[[[Window alloc] init] autorelease] makeMainWindow];
[NSApp run];
}
但是根本没有调用drawRect(),这是什么问题?
这个过程是不是应该像Windows一样,在有需要重绘的脏区时调用?
So, how do I complete my code with NSView?
代替使用您的示例,我建议您考虑以下内容。这是另一种以编程方式创建 Cocoa 应用程序的方法,并演示了在自定义 NSView 中使用 -drawRect()。请注意,window 可调整大小,类似于您发布的内容。要在Xcode中运行先创建一个objc工程,然后删除给你提供的AppDelegate,删除原代码后将下面的内容粘贴到main.m中:
#import <Cocoa/Cocoa.h>
@interface CustomView : NSView
//methods automatically called
@end
@implementation CustomView
- (id)initWithFrame:(NSRect)frameRect {
if ((self = [super initWithFrame:frameRect]) != nil) {
// Add initialization code here
}
return self;
}
- (void)drawRect:(NSRect)rect {
// **** Background **** //
[[NSColor orangeColor] set];
[NSBezierPath fillRect:rect];
NSBezierPath *path = [NSBezierPath bezierPathWithOvalInRect:NSInsetRect([self bounds], 30,30)];
[[NSColor redColor] set];
[path fill];
[[NSColor whiteColor] set];
[path setLineWidth:1.0];
[path stroke];
}
// Use this if you want 0,0 (origin) to be top, left //
// Otherwise origin will be at bottom, left (Unflipped) //
-(BOOL)isFlipped {
return YES;
}
@end
@interface AppDelegate : NSObject <NSApplicationDelegate> {
NSWindow *window;
}
- (void) myBtnAction: (id)sender;
- (void) buildMenu;
- (void) buildWnd;
@end
@implementation AppDelegate
- (void) myBtnAction: (id)sender {
NSBeep();
}
- (void) buildMenu {
NSMenu *menubar = [NSMenu new];
NSMenuItem *appMenuItem = [NSMenuItem new];
[menubar addItem:appMenuItem];
[NSApp setMainMenu:menubar];
NSMenu *appMenu = [NSMenu new];
NSMenuItem *quitMenuItem = [[NSMenuItem alloc] initWithTitle:@"Quit"
action:@selector(terminate:) keyEquivalent:@"q"];
[appMenu addItem:quitMenuItem];
[appMenuItem setSubmenu:appMenu];
}
- (void) buildWnd {
#define _wndW 500
#define _wndH 450
window = [[NSWindow alloc] initWithContentRect: NSMakeRect( 0, 0, _wndW, _wndH )styleMask: NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable backing: NSBackingStoreBuffered defer: NO];
[window center];
[window setTitle: @"Custom View"];
[window makeKeyAndOrderFront: nil];
// **** Create an instance of CustomView (NSView) **** //
CustomView *view = [[CustomView alloc]initWithFrame:NSMakeRect( 20, 80, _wndW - 40, _wndH - 100 )];
[view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
[[window contentView] addSubview:view];
// **** Button **** //
NSButton *myBtn =[[NSButton alloc]initWithFrame:NSMakeRect( 30, 30, 95, 30 )];
[myBtn setBezelStyle:NSBezelStyleRounded ];
[myBtn setTitle: @"Beep"];
[myBtn setAction: @selector (myBtnAction:)];
[[window contentView] addSubview: myBtn];
// **** Quit btn **** //
NSButton *quitBtn = [[NSButton alloc]initWithFrame:NSMakeRect( _wndW - 50, 10, 40, 40 )];
[quitBtn setBezelStyle:NSBezelStyleCircular ];
[quitBtn setTitle: @"Q" ];
[quitBtn setAutoresizingMask: NSViewMinXMargin];
[quitBtn setAction:@selector(terminate:)];
[[window contentView] addSubview: quitBtn];
}
- (void) applicationWillFinishLaunching: (NSNotification *)notification {
[self buildMenu];
[self buildWnd];
}
- (void) applicationDidFinishLaunching: (NSNotification *)notification {
}
@end
int main() {
NSApplication *application = [NSApplication sharedApplication];
AppDelegate *appDelegate = [[AppDelegate alloc] init];
[application setDelegate:appDelegate];
[application run];
return 0;
}
我是编程 OS X Cocoa 应用程序的新手。所以请同情。我想让一个应用程序变得简单,但我已经阻止了自己在应用程序中绘制图像。
此代码应绘制多个图像并在调整大小时或最大化 window 应用程序时更改排列。
#include <Cocoa/Cocoa.h>
#ifndef NSWindowStyleMaskTitled
#define NSWindowStyleMaskTitled NSTitledWindowMask
#define NSWindowStyleMaskClosable NSClosableWindowMask
#define NSWindowStyleMaskMiniaturizable NSMiniaturizableWindowMask
#define NSWindowStyleMaskResizable NSResizableWindowMask
#define NSEventMaskAny NSAnyEventMask
#endif
@interface Window : NSWindow {
NSTimer* mTimer;
}
- (instancetype)init;
- (BOOL) acceptsFirstResponder;
- (BOOL) acceptsFirstMouse: (NSEvent*) pEvent;
- (void) viewDidMoveToWindow;
- (void) drawRect: (NSRect) rect;
- (void) onTimer: (NSTimer*) pTimer;
- (void) getMouseXY: (NSEvent*) pEvent x: (int*) pX y: (int*) pY;
- (void) mouseDown:(NSEvent*)event;
- (void) mouseUp: (NSEvent*) event;
- (void) mouseDragged: (NSEvent*) event;
- (void) rightMouseDown: (NSEvent*) event;
- (void) rightMouseUp: (NSEvent*) event;
- (NSDragOperation) draggingEntered:(id <NSDraggingInfo>)sender;
- (BOOL) performDragOperation:(id <NSDraggingInfo>)sender;
- (void) windowDidResize:(NSNotification*)notification;
- (void) windowDidMiniaturize:(NSNotification*)sender;
- (void) windowDidDeMiniaturize:(NSNotification*)sender;
- (BOOL) windowShouldClose:(id)sender;
@end
@implementation Window
- (instancetype)init {
mTimer = 0;
double sec = 1.0 / 24;
mTimer = [NSTimer timerWithTimeInterval:sec target:self selector:@selector(onTimer:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer: mTimer forMode: (NSString*) kCFRunLoopCommonModes];
[self registerForDraggedTypes:[NSArray arrayWithObjects: NSFilenamesPboardType, nil]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidMiniaturize:) name:NSWindowDidMiniaturizeNotification object:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidDeMiniaturize:) name:NSWindowDidDeminiaturizeNotification object:self];
[super initWithContentRect:NSMakeRect(0, 0, 500, 300) styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable backing:NSBackingStoreBuffered defer:NO];
[self setTitle:@"Hello world"];
[self center];
[self setOpaque:NO];
[self setHasShadow:YES];
//[self setBackgroundColor:[NSColor clearColor]];
[self setBackgroundColor:[NSColor grayColor]];
[self setIsVisible:YES];
return self;
}
- (BOOL) acceptsFirstResponder {
return YES;
}
- (BOOL) acceptsFirstMouse: (NSEvent*) pEvent {
return YES;
}
- (void) viewDidMoveToWindow {
NSWindow* pWindow = [self window];
if (pWindow) {
[pWindow makeFirstResponder: self];
[pWindow setAcceptsMouseMovedEvents: YES];
}
}
- (void) drawRect: (NSRect) rect {
NSLog(@"drawRect %f, %f, %f", rect.origin.x, rect.origin.y, rect.size.width);
}
- (void) onTimer: (NSTimer*) pTimer {
NSRect r;
if (pTimer == mTimer) {
//NSLog(@"mTimer");
}
}
- (void) getMouseXY: (NSEvent*) pEvent x: (int*) pX y: (int*) pY {
NSPoint pt = [pEvent locationInWindow];
*pX = (int) pt.x;
//*pY = mGraphics->Height() - (int) pt.y;
*pY = 555 - (int) pt.y;
NSLog(@"%f , %f", pt.x, pt.y);
}
- (void)mouseDown:(NSEvent*)event {
NSLog(@"mouseDown called");
}
- (void) mouseUp: (NSEvent*) event {
int x, y;
[self getMouseXY:event x:&x y:&y];
}
- (void) mouseDragged: (NSEvent*) event {
int x, y;
[self getMouseXY:event x:&x y:&y];
}
- (void) rightMouseDown: (NSEvent*) event {
int x, y;
[self getMouseXY:event x:&x y:&y];
}
- (void) rightMouseUp: (NSEvent*) event {
int x, y;
[self getMouseXY:event x:&x y:&y];
}
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>) sender {
NSPasteboard *pboard = [sender draggingPasteboard];
return (([pboard.types containsObject:NSFilenamesPboardType]) ? NSDragOperationLink : NSDragOperationNone);
}
- (BOOL)performDragOperation:(id <NSDraggingInfo>) sender {
NSPasteboard *pboard = [sender draggingPasteboard];
if ( [[pboard types] containsObject:NSFilenamesPboardType] ) {
//NSPoint pt = [self convertPoint:[sender draggingLocation] fromView:nil];
for (NSString *path in [pboard propertyListForType:NSFilenamesPboardType]) {
const char* tmp=[path UTF8String];
NSLog(@"%@", path);
//if (mGraphics) {
//mGraphics->OnMouseDrop(pt.x, mGraphics->Height() - pt.y, (char*)tmp);
//break;
//}
}
}
return YES;
}
- (void)windowDidResize:(NSNotification*)notification {
//NSLog(@"Resize");
}
- (void)windowDidMiniaturize:(NSNotification*)notification {
NSLog(@"Minimize");
}
- (void)windowDidDeMiniaturize:(NSNotification*)notification {
NSLog(@"DeMinimize");
}
- (BOOL)windowShouldClose:(id)sender {
[NSApp terminate:sender];
return YES;
}
@end
int main(int argc, char* argv[]) {
[NSApplication sharedApplication];
[[[[Window alloc] init] autorelease] makeMainWindow];
[NSApp run];
}
但是根本没有调用drawRect(),这是什么问题?
这个过程是不是应该像Windows一样,在有需要重绘的脏区时调用?
So, how do I complete my code with NSView?
代替使用您的示例,我建议您考虑以下内容。这是另一种以编程方式创建 Cocoa 应用程序的方法,并演示了在自定义 NSView 中使用 -drawRect()。请注意,window 可调整大小,类似于您发布的内容。要在Xcode中运行先创建一个objc工程,然后删除给你提供的AppDelegate,删除原代码后将下面的内容粘贴到main.m中:
#import <Cocoa/Cocoa.h>
@interface CustomView : NSView
//methods automatically called
@end
@implementation CustomView
- (id)initWithFrame:(NSRect)frameRect {
if ((self = [super initWithFrame:frameRect]) != nil) {
// Add initialization code here
}
return self;
}
- (void)drawRect:(NSRect)rect {
// **** Background **** //
[[NSColor orangeColor] set];
[NSBezierPath fillRect:rect];
NSBezierPath *path = [NSBezierPath bezierPathWithOvalInRect:NSInsetRect([self bounds], 30,30)];
[[NSColor redColor] set];
[path fill];
[[NSColor whiteColor] set];
[path setLineWidth:1.0];
[path stroke];
}
// Use this if you want 0,0 (origin) to be top, left //
// Otherwise origin will be at bottom, left (Unflipped) //
-(BOOL)isFlipped {
return YES;
}
@end
@interface AppDelegate : NSObject <NSApplicationDelegate> {
NSWindow *window;
}
- (void) myBtnAction: (id)sender;
- (void) buildMenu;
- (void) buildWnd;
@end
@implementation AppDelegate
- (void) myBtnAction: (id)sender {
NSBeep();
}
- (void) buildMenu {
NSMenu *menubar = [NSMenu new];
NSMenuItem *appMenuItem = [NSMenuItem new];
[menubar addItem:appMenuItem];
[NSApp setMainMenu:menubar];
NSMenu *appMenu = [NSMenu new];
NSMenuItem *quitMenuItem = [[NSMenuItem alloc] initWithTitle:@"Quit"
action:@selector(terminate:) keyEquivalent:@"q"];
[appMenu addItem:quitMenuItem];
[appMenuItem setSubmenu:appMenu];
}
- (void) buildWnd {
#define _wndW 500
#define _wndH 450
window = [[NSWindow alloc] initWithContentRect: NSMakeRect( 0, 0, _wndW, _wndH )styleMask: NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable backing: NSBackingStoreBuffered defer: NO];
[window center];
[window setTitle: @"Custom View"];
[window makeKeyAndOrderFront: nil];
// **** Create an instance of CustomView (NSView) **** //
CustomView *view = [[CustomView alloc]initWithFrame:NSMakeRect( 20, 80, _wndW - 40, _wndH - 100 )];
[view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
[[window contentView] addSubview:view];
// **** Button **** //
NSButton *myBtn =[[NSButton alloc]initWithFrame:NSMakeRect( 30, 30, 95, 30 )];
[myBtn setBezelStyle:NSBezelStyleRounded ];
[myBtn setTitle: @"Beep"];
[myBtn setAction: @selector (myBtnAction:)];
[[window contentView] addSubview: myBtn];
// **** Quit btn **** //
NSButton *quitBtn = [[NSButton alloc]initWithFrame:NSMakeRect( _wndW - 50, 10, 40, 40 )];
[quitBtn setBezelStyle:NSBezelStyleCircular ];
[quitBtn setTitle: @"Q" ];
[quitBtn setAutoresizingMask: NSViewMinXMargin];
[quitBtn setAction:@selector(terminate:)];
[[window contentView] addSubview: quitBtn];
}
- (void) applicationWillFinishLaunching: (NSNotification *)notification {
[self buildMenu];
[self buildWnd];
}
- (void) applicationDidFinishLaunching: (NSNotification *)notification {
}
@end
int main() {
NSApplication *application = [NSApplication sharedApplication];
AppDelegate *appDelegate = [[AppDelegate alloc] init];
[application setDelegate:appDelegate];
[application run];
return 0;
}