BLOG ARTICLE AppKit | 1 ARTICLE FOUND

  1. 2008.01.09 다이알로그 윈도우 구현 (2)

다이알로그는 MS 윈도우의 MessageBox와 같이 간단한 메시지 출력이나 사용자로 부터 선택사항을 입력 받는 윈도우입니다. cocoa에서 다이알로그를 구현하는 방법에 대해서 간단하게 알아 보겠습니다.


1. NSAlert

사용자 삽입 이미지

AppKit의 NSAlert은 위와 같이 간단한 경고창을 출력하게 해주는 기본 클래스 입니다. 아래는 NSAlert을 사용하여 위와 같은 알림창을 뛰우는 간단한 예입니다.

int returnValue;
NSAlert *alert = [[NSAlert alloc] init];
   
[alert addButtonWithTitle:@"button1"];
[alert addButtonWithTitle:@"button2"];
[alert addButtonWithTitle:@"button3"];
[alert setMessageText:
        [NSString stringWithUTF8String:"알림입니다."]];
[alert setInformativeText:
        [NSString stringWithUTF8String:"이알림은 테스트용 입니다."]];
[alert setAlertStyle:NSWarningAlertStyle];
  
returnValue = [alert runModal];
   
[alert release];

1) addButtonWithTitle:
버튼을 추가합니다.

2) setMessageText:
출력될 메시지를 설정합니다.

3) setInfomativeText:
메시지에 대한 상세 설명을 설정합니다.

4) setAlertStyle:
경고창의 아이콘을 결정합니다. 아이콘의 종류는 아래와 같습니다.

> NSWarningAlertStyle
일반적인 경고창입니다.

> NSInformationalAlertStyle
NSWarningAlertStyle과 동일합니다. 하위 호환성을 위해서 존재하는 것 같습니다

> NSWarningAlertStyle
사용자 삽입 이미지
좌측과 같이 어플리케이션 아이콘 뒤로 경고 아이콘을 출력합니다.




5) runModal
경고창을 오픈합니다. 종료시에는 사용자가 클릭한 버튼 값을 반환합니다. 첫번째 버튼부터 아래와 같이 정의되어 있습니다. 버튼이 세개 이상일 경우에는 1003부터 순차적으로 증가된 값을 반환합니다.

enum =  {
    NSAlertFirstButtonReturn  = 1000,
    NSAlertSecondButtonReturn  = 1001,
    NSAlertThirdButtonReturn  = 1002
};

6) Help
사용자 삽입 이미지

위와 같이 경고창 좌측에 Help(?) 버튼을 두고 사용자가 클릭시 원하는 행동을 지정할 수 있습니다. NSAlert에서 아래와 같이 속성을 설정합니다.

[alert setShowsHelp:YES]

   경고창에 Help 버튼을 출력합니다.

[alert setDelegate:self];
   Help 버튼 클릭시 alertShowHelp 메시지를 받을 오브젝트를 설정합니다.

아래는 버튼 클릭 시 웹페이지 또는 html 파일을 오픈하는 예입니다.

- (BOOL)alertShowHelp:(NSAlert *)alert
{   
    NSURL *url = [NSURL URLWithString:@"http://www.cocoadev.co.kr"];
    return [[NSWorkspace sharedWorkspace] openURL:url];

/* 번들 리소스의 help.html에서 불러 옵니다. 

    NSString *path = [[NSBundle mainBundle]
            pathForResource:@"help" ofType:@"html"];
    return [[NSWorkspace sharedWorkspace] openFile:path];
*/   
}

NSAlert *alert = [[NSAlert alloc] init];
   
[alert addButtonWithTitle:@"button1"];
[alert addButtonWithTitle:@"button2"];
[alert addButtonWithTitle:@"button3"];
   
[alert setMessageText:
        [NSString stringWithUTF8String:"알림입니다."]];
[alert setInformativeText:
        [NSString stringWithUTF8String:"이알림은 테스트용 입니다."]];
[alert setAlertStyle:NSCriticalAlertStyle];

[alert setShowsHelp:YES];
[alert setDelegate:self];
   
returnValue = [alert runModal];
   
[alert release];


2. Sheet
사용자 삽입 이미지

Sheet은 위와 같이 윈도우의 타이틀바 밑으로 내려오는 판넬을 의미합니다. NSAlert의 beginSheetModalForWindow으로 구현할 수 있으며 사용예는 아래와 같습니다.

- (void)alertDidEnd:(NSAlert *)alert
           returnCode:(int)returnCode
          contextInfo:(void *)contextInfo
{
    NSLog(@"returnCode %d", returnCode);
}

NSAlert *alert = [[NSAlert alloc] init];
   
[alert addButtonWithTitle:@"button1"];
[alert addButtonWithTitle:@"button2"];
[alert addButtonWithTitle:@"button3"];
[alert setMessageText:
        [NSString stringWithUTF8String:"알림입니다."]];
[alert setInformativeText:
        [NSString stringWithUTF8String:"이알림은 테스트용 입니다."]];
[alert setAlertStyle:NSWarningAlertStyle];
   
[alert beginSheetModalForWindow:[NSApp mainWindow]
                      modalDelegate:self
                     didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
                        contextInfo:NULL];  

1) Window
Sheet의 부모 윈도우를 설정합니다. 이 윈도우의 타이틀 바에서 Sheet가 오픈됩니다.

2) modalDelegate
Sheet의 메시지 처리를 위임 받을 오브젝트를 설정합니다. 이 오브젝트가 didEndSelector에서 설정된 메소드로 종료 메시지를 받습니다.

3) didEndSelector
Sheet가 종료될 때 불려지는 메소드입니다. 사용자의 선택에 따라 처리할 내용이 있을 경우, 여기서 처리합니다. 사용하지 않을 경우에는 nil로 설정합니다.

4) contextInfo
종료시 호출되는 메소드(didEndSelector)에 전달되는 사용자 정의 인자입니다.  종료 메소드에서 필요한 정보가 있을 경우에 설정합니다.


3. NSRunAlertPanel
NSRunAlertPanel 함수를 이용하면 NSAlert 클래스를 이용하는 것보다 편리하게 경고창을 구현할 수 있습니다. NSRunAlertPanel은 아래과 같이 선언되어 있습니다.

NSInteger NSRunAlertPanel (
  NSString *title,
  NSString *message,
  NSString *defaultButton,
  NSString *alternateButton,
  NSString *otherButton,
  ...
);

title, message,  세개의 버튼 타이틀을 인자로 가지고 있습니다. 사용하지 않는 버튼은 nil로 선언하면 출력되지 않습니다. 유의 하실 점은 마지막에 "..."로 가변인수를 가지고 있어 편리하게 사용할 수 있다는 점입니다.

이 가변인수는 message필드에 적용되며 실제 사용 예는 아래와 같습니다.
 
NSRunAlertPanel([NSString stringWithUTF8String:"알림입니다."],
      [NSString stringWithUTF8String:"이알림은 %d, %s 입니다."],
      @"default", @"alternate", @"other", 10, "test");

이를 실행하면 아래와 같습니다.
사용자 삽입 이미지

반환값은 아래와 같습니다. 오류(NSAlertErrorReturn)가 있을 경우를 제외하고는 각각 클릭된 버튼값을 반환합니다.

enum {
   NSAlertDefaultReturn = 1,
   NSAlertAlternateReturn = 0,
   NSAlertOtherReturn = -1,
   NSAlertErrorReturn = -2
};

NSAlert의 NSWarningAlertStyle과 같은 아이콘을 출력하실려면, NSRunCriticalAlertPanel을 사용하시면 됩니다.


4. NSBeginAlertSheet


사용자 삽입 이미지

 NSRunAlertPanel과 같은 사용법으로 NSAlert 클래스를 이용하는 것보다 편리하게 Sheet를 구현할 수 있습니다. NSBeginAlertSheet은 아래과 같이 선언되어 있습니다.

void NSBeginAlertSheet (
   NSString *title,
   NSString *defaultButton,
   NSString *alternateButton,
   NSString *otherButton,
   NSWindow *docWindow,
   id modalDelegate,
   SEL didEndSelector,
   SEL didDismissSelector,
   void *contextInfo,
   NSString *msg,
   ...
);

사용법은 이전의 예와 유사하며, 새로 추가된 인자만 설명하겠습니다.

1) didDismissSelector
Sheet가 사라될 때 불려지는 메소드이며, 사용하지 않을 경우에는 nil로 설정합니다.
didEndSelector보다 나중에 호출됩니다.

2) contextInfo
종료시 호출되는 메소드(didEndSelector, didDismissSelector)에 전달되는 사용자 정의 인자입니다.  종료 메소드에서 필요한 정보가 있을 경우에 설정합니다.

Sheet 사용 예는 아래와 같습니다.

- (void)sheetDidEndShouldDelete: (NSWindow *)sheet
                     returnCode: (int)returnCode
                    contextInfo: (void *)contextInfo
{
    NSLog(@"result %d", returnCode);
}

NSBeginAlertSheet([NSString stringWithUTF8String:"알림입니다."],
                      @"default",
                      @"alternate",
                      @"other",
                      [NSApp mainWindow],
                      self,
                      @selector(sheetDidEndShouldDelete:returnCode:contextInfo:),
                      NULL,
                      NULL,
                      [NSString stringWithUTF8String:"이알림은 %d, %s 입니다."],
                      10, "test");

NSAlertParnel과 동일하게 NSBeginCriticalAlertSheet을 사용하면 경고 아이콘을 출력할 수 있습니다.