02 컨트롤 다루기 - 한줄 말하기 애플리케이션
September 30th, 2007
지난글: 01 코코아와의 만남 - 난수 생성 애플리케이션 / 루비 코코아 프로그래밍
이번에는 컨트롤을 사용하는 간단한 예제로 책의 4장~5장에서 설명하고 있다. 아울렛과 액션을 지정하는 법만 알면 쉽게 따라할 수 있는 예제였다.
SpeakLine 예제
NSTextField의 값을 NSSpeechSynthesizer를 이용해 읽어주는 간단한 애플리케이션이다. 왼쪽의 색상 선택기(NSColorWell)은 이유없이 붙어 있다 :)
도우미 객체와 델리게이트
코코아 컨트롤과 정보(값이든 이벤트든)를 주고 받는 방식은 델리게이션(Delegation)이다. 내가 너를 위한 메서드들을 구현하고 있으니 필요한 기능이 있으면 나한테 위임해라고 컨트롤에 요청하는 식이다. 일관성있고 깔끔한 구현같다.
- @speech_synth.setDelegate(self)
이 예제에서는 델리게이트를 설정해 NSSpeechSynthesizer의 종료 이벤트를 처리하고 TableView의 DataSource 역할을 수행하고, 또 TableView의 변경 이벤트들도 처리했다.
책에 보면 델리케이트를 구현할 때 발생하는 일반적인 오류로 이름을 잘못 적는 경우와 아웃렛 지정을 건너뛰는 것을 들고 있는데, 짧은 예제를 만들면서 두 가지 모두 겪게 되었다. 익숙해지기 전까지는 상당히 신경을 쓰고 있어야할 것 같다.
다음은 컨트롤러의 전체 소스 코드이다.
- require 'osx/cocoa'
class AppController < OSX::NSObject
ib_outlet :textField
ib_outlet :colorWell
ib_outlet :stopButton
ib_outlet :tableView
ib_action :sayIt
ib_action :stopIt
ib_action :changeTextColor
def initialize
OSX::NSLog 'initialized'
@speech_synth = OSX::NSSpeechSynthesizer.alloc.initWithVoice(nil)
@speech_synth.setDelegate(self)
end
def awakeFromNib
OSX::NSLog 'setting initial color for color well'
@colorWell.setColor(@textField.textColor)
default_voice = available_voices.indexOfObject(OSX::NSSpeechSynthesizer.defaultVoice)
@tableView.selectRow_byExtendingSelection(default_voice, false)
@tableView.scrollRowToVisible(default_voice)
end
########################################
## Actions
def sayIt(sender)
str = @textField.stringValue
return if str.empty?
@speech_synth.startSpeakingString(str)
OSX::NSLog "Have started to say: #{str}"
@stopButton.enabled = true
end
def stopIt(sender)
OSX::NSLog "Stopping"
@speech_synth.stopSpeaking
end
def changeTextColor(sender)
OSX::NSLog "changing the color"
@textField.setTextColor(sender.color)
end
########################################
## OSX::NSSpeechSynthesizer
def speechSynthesizer_didFinishSpeaking(sender, finished)
OSX::NSLog "finished: #{finished}"
@stopButton.enabled = false
end
def available_voices
OSX::NSSpeechSynthesizer.availableVoices
end
########################################
## TableView
def numberOfRowsInTableView(tableView)
available_voices.count
end
def tableView_objectValueForTableColumn_row(tableView, tableColumn, row)
voice = available_voices.objectAtIndex(row)
OSX::NSSpeechSynthesizer.attributesForVoice(voice).valueForKey(OSX::NSVoiceName)
end
def tableViewSelectionDidChange(notification)
row = @tableView.selectedRow
return if row == -1
selected = available_voices.objectAtIndex(row)
@speech_synth.voice = selected
OSX::NSLog "new voice: #{selected}"
end
def selectionShouldChangeInTableView(tableView)
return true unless @speech_synth.isSpeaking
OSX.NSBeep
false
end
end
전체 소스 파일: SpeakLine.zip
후기
아직 코코아 프레임워크의 메시지들의 명명 규칙을 잘 모르겠다. 일관성 있는 것 같으면서도 곰곰히 쳐다보면 뭔가 어색해보인다. 익숙하지 않아서 인지, 원래 복잡한 것인지 잘 모르겠다. 그리고 루비 코코아가 Objective-C에 비해 코딩량은 확실히 적지만, IDE의 도움(코드 생성)을 못 받고 있어서 초보자에게는 약간 어려운 부분이 있어 보인다. 다음 버전 XCode에서는 루비 지원도 보강될까?
다음 예제는 03 친해지길 바래 - 직원 급여 관리 애플리케이션. 이제 서서히 복잡해진다(전체보기: 루비 코코아 프로그래밍).




September 30th, 2007 at 04:30 PM (myRuby.net) 스프링노트에 정리하며 책을 읽으니, 속도는 느리지만 여러모로 더 즐겁네요. 이렇게 읽어면 좋을만한 책이 꽤 있을 것 같습니다.
September 30th, 2007 at 04:44 PM 시간이 지나면서 점점 눈으로 대충 공부하는 버릇이 생겨서 걱정인데… 스프링노트에 정리하고 슬러거에 배포하고 좋은 시스템 같아요. 스프링노트 클라이언트를 eclipse RCP 어플리케이션으로 만들면 플랫폼 독립적이랍니다. -0-''
October 1st, 2007 at 01:12 AM (myRuby.net) 와..!! 스프링노트에서 문식님 글 잘 보고 있습니다.저도 해보려고 했던건데 문식님이 먼저 시작하셨네요 흐흐; 문식님 루비코드 보고 많이 배워야겠습니다 ^^
October 1st, 2007 at 01:50 AM 아- 아- 아-
October 1st, 2007 at 02:25 PM Jenix// 저도 Jenix님 책과 블로그에서 많이 배워요~ 좋은 책 감사합니다.