TheSpecUIframework:Chapter 02

From 흡혈양파의 번역工房
Jump to navigation Jump to search
처음 사용 및 예제

처음 사용 및 예제

이 책을 시작하기 위해 몇 가지 예제를 이용함으로서 Spec 의 사용법을 설명합니다. 먼저 작지만 완전한 사용자 인터페이스를 작성한 이후에, 기존 위젯을 구성하는 방법에 대한 몇 가지 예를 보여드리겠습니다. 이 예제들을 통해 기본 사용자 인터페이스를 구축 할 수 있습니다.


이 장을 끝낸 뒤에 Spec 위젯의 재사용에 대한 다음 장을 읽어보시기 바랍니다. Spec 위젯의 핵심 입니다. 이 두 장을 읽는다면 Spec 사용자 인터페이스를 의도 한대로 구성 할 수 있게 됩니다. 이 책자의 나머지 부분을 참고 자료로 사용할 수는 있지만, 그럼에도 불구하고 다른 장들에 대해서도 간략하게 살펴볼 것을 권장합니다.


고객 만족 UI

Spec UI 의 첫 번째 예제에서는 간단한 고객 만족도 UI를 구성해서, 사용자가 세 가지 버튼 중 하나를 클릭하여 서비스에 대한 피드백을 제공 할 수 있도록 합니다. (고객의 반응(피드백)을 기록하고 처리하기는 해야 하지만, 이 문서의 범위를 벗어나게 됩니다).

그림 2-1에서 UI의 스크린 샷을 확인할 수 있습니다.
그림 2-1 고객 만족 UI 스크린샷


UI 및 변수 접근자(accessors) 클래스 만들기

Spec 의 모든 사용자 인터페이스는 ComposableModel 의 하위 클래스이므로, UI 를 만드는 첫 번째 단계는 하위 클래스를 만드는 것부터 시작됩니다.

ComposableModel subclass: #CustomerSatisfaction
	instanceVariableNames: 'buttonHappy buttonNeutral buttonBad screen'
	classVariableNames: ''
	package: 'Spec-BuildUIWithSpec'


클래스의 인스턴스 변수는 UI 에 포함 된 위젯을 포함합니다. 이 예제에서는 세 개의 버튼과 텍스트 화면이 있습니다. 이러한 위젯들의 인스턴스 변수에 대한 접근자도 정의해야하며, Spec 인터프리터는 UI 구성 과정에서 이를 사용합니다.


Gnome3 notice header.png
UI 위젯의 인스턴스 변수에 대한 접근자 생성을 항상 기억하십시오.
Gnome3 notice footer.png


이 클래스의 메소드는 초기화 및 구성을 제공합니다. label 및 action 뿐만 아니라 상호 작용의 논리도 포함됩니다. GUI의 기본 설계, 즉 위젯이 배치되는 방식은 클래스 측면의 메소드에 의해 정의됩니다.[1]


하위 위젯 인스턴스화 및 구성

ComposableModel 의 하위 클래스는 사용자 인터페이스에서 사용되는 위젯을 인스턴스화하고 구성하는 initializeWidgets 메소드를 정의 할 책임이 있습니다. 이부분에 대해서 차근차근히 살펴보도록 하겠습니다. 먼저 위젯 인스턴스화를 살펴보겠습니다:

CustomerSatisfaction >> initializeWidgets

	"widget instantiation"
	screen := self newLabel.
	buttonHappy := self newButton.
	buttonNeutral := self newButton.
	buttonBad := self newButton.


ComposableModel 은 표준 위젯 (newButton, newCheckBox, newDropList, ...) 생성을위한 메시지를 정의합니다. 이 모든 것은 widget 프로토콜에 정의되어 있습니다.


Gnome3 notice header.png
UI 의 일부인 위젯을 인스턴스화하려면 new 를 호출하지 마십시오.
Gnome3 notice footer.png


Gnome3 notice header.png
위젯을 인스턴스화하는 또 다른 방법은 클래스를 인수로 사용하여 instantiate: 메시지를 사용하는 것입니다. 예를 들자면 다음과 같은 코드가 됩니다. screen := self instantiate: LabelModel. 이 코드는 비표준 위젯을 인스턴스화 할 수 있게 하지만, 당연히 표준 위젯에도 사용될 수 있습니다.
Gnome3 notice footer.png


두 번째로 UI의 버튼을 구성해 보겠습니다. label: 메시지는 레이블을 정의하고 icon: 메시지는 레이블 근처에 표시 될 아이콘을 지정합니다. 이제부터 보여드릴 코드는 Pharo 6 를 위한 것입니다. Pharo 5 에서 작동시킨다면 자신의 iconNamed: 를 Smalltalk UI 아이콘 iconNamed: 로 바꾸는 작동을 하게 됩니다.

[ ... continued ... ]
	"widget configuration"
	screen label: 'Please give us your feedback.'.
	buttonHappy
		label: 'Happy';
		icon: (self iconNamed: #thumbsUp).
	buttonNeutral
		label: 'Neutral';
		icon: (self iconNamed: #user).
	buttonBad
		label: 'Bad';
		icon: (self iconNamed: #thumbsDown).


세번째 이자 마지막으로, 포커스 순서를 정의하는 것은 키보드로 탐색하는 경우에 유용합니다.

[ ... continued ... ]
	"specification of order of focus"
	self focusOrder
		add: buttonHappy;
		add: buttonNeutral;
		add: buttonBad


ComposableModel 서브 클래스는 initializePresenter 메소드를 정의 할 수도 있습니다. 이 메소드의 목적은 서로 다른 위젯 간에 상호 작용을 구성하는 것입니다.

CustomerSatisfaction >> initializePresenter

	buttonHappy action: [ screen label: buttonHappy label ].
	buttonNeutral action: [ screen label: buttonNeutral label ].
	buttonBad action: [ screen label: buttonBad label ].


action: 메시지를 사용하여 버튼을 클릭 할 때 수행 할 작업을 지정합니다. 이 경우 화면에 표시되는 내용을 변경하여 선택 사항이 등록되었다는 피드백을 제공합니다. action: 메시지는 버튼 API의 일부입니다. 다른 상황에서는 지정된 이벤트가 발생하면 다른 메시지를 위젯 서브 파트로 보내도록 지정합니다.


Gnome3 notice header.png
요약하자면, '자체적인' 위젯 설정은 initializeWidgets 에 들어가며, '외부와 연동되는' 부분의 위젯 설정은 initializePresenter 에 들어갑니다.
Gnome3 notice footer.png


위젯은 이제 정의 및 구성되었지만 UI에서의 배치가 지정된 것은 아닙니다. UI 에서의 배치는 클래스 측 메소드인 defaultSpec 의 역할입니다.

CustomerSatisfaction class >> defaultSpec
	^ SpecLayout composed
		newRow: [ :row |
			row add: #buttonHappy; add: #buttonNeutral; add: #buttonBad ]
		origin: 0 @ 0 corner: 1 @ 0.7;
		newRow: [ :row | row add: #screen ]
		origin: 0 @ 0.7 corner: 1 @ 1;
		yourself


이 레이아웃에서는 UI에 두 개의 행을 추가하게 됩니다. 하나는 버튼이고 다른 하나는 텍스트 화면입니다. 위젯 레이아웃을 정의하는 것은 여러 가지로 가능한 요구 사항을 가진 복잡한 프로세스이므로 이 장에서는 레이아웃 사양에 대해 자세히 이야기하지는 않을 것입니다. 자세한 내용은 5장을 참조해 주세요.


Gnome3 notice header.png
add: 메시지의 인수는 접근자의 심볼이 됩니다. 왜나하면 Spec 인터프리터가 레이아웃을 작동시킬 때 위젯을 불러오기 위해서 이 메서드를 호출하기 때문입니다.
Gnome3 notice footer.png


제목 및 창 크기를 정의하기, UI 의 열기 및 닫기

창의 제목과 초기 크기를 설정하려면 두 가지 메서드를 정의해야합니다.:

CustomerSatisfaction >> title
	^ 'Customer Satisfaction Survey'.

CustomerSatisfaction >> extent
	^ 400@100


title 메서드는 제목으로 사용될 문자열을 반환하고 extent 메서드는 창의 크기를 지정하는 포인트를 반환합니다. UI 를 열려면, 클래스의 인스턴스를 만들어야하며 openWithSpec 메시지를 보내야합니다. 메시지를 보내면 창이 열리며, 열린 창에서는 코드를 닫을 수 있는 WindowModel 인스턴스가 반환됩니다.

 | ui |
 ui := CustomerSatisfaction new openWithSpec.
 [ ... do a lot of stuff until the UI needs to be closed ...]
 ui close.


대화 상자를 열거나 about 텍스트를 설정하는 방법등 창 관리에 대한 추가 정보는 6 장을 참고해주세요.


이것으로 Spec 사용자 인터페이스의 첫 번째 예제를 마치겠습니다. 이제부터는 이러한 사용자 인터페이스에서 사용할 수 있는 다른 위젯을 구성하는 방법에 대한 예제가 계속됩니다.


Fun with Lists

위젯을 구성하는 방법을 보여주는 명확한 예제로서, 서로 다른 배경색을 사용하는 목록과 아이콘을 보여주는 목록의 두 가지 예제를 확인할 수 있습니다.


이 예제는 Spec의 두 가지 중요한 기능을 보여줍니다:

  1. 모든 위젯은 창에서 열 수 있습니다. 이는 위에 표시된 것처럼 복잡한 UI 와 표준 위젯 사이에 근본적인 차이는 없기 때문입니다.
  2. 모든 위젯은 설정 가능하며, 설정에 대한 메소드는 api 프로토콜로 분류됩니다.


항목의 배경으로 색상 등록하기

그림 2-2 와 같이 요소(elements)의 배경색이 각각 다르게 되어있는 ListModel 예제부터 시작하겠습니다. 목록에있는 항목은 각각 다른 색상의 이름이며, 목록에는 해당 색상의 배경을 사용하여 목록이 표시됩니다.


다음의 코드는 이런 내용이 어떻게 수행되는지를 보여줍니다:

 | registeredColorsList |
 registeredColorsList := ListModel new.
 registeredColorsList
	items: Color registeredColorNames;
	backgroundColorBlock: [ :item | Color named: item ];
	title: 'Registered colors'.
 registeredColorsList openWithSpec


이렇게 하면 ListModel API 의 일부인 다음 메시지가 표시됩니다.

그림 2-2 배경색이 수정된 목록의 스크린샷


  • items: 메시지는 목록의 요소를 설정합니다.
  • backgroundColorBlock: 메시지는 현재 요소의 배경색을 결정하기 위해 실행되어야할 블록을 지정하게 됩니다. 단일 매개 변수, 즉 목록 항목이있는 블록을 사용합니다.
  • title: 메시지는 목록이 들어있는 창의 제목을 설정합니다.


아이콘의 목록

두 번째 예제에서는 현재 테마의 아이콘과 IconListModel 에 대한 해당 셀렉터(selector)를 포함하는 목록을 보여줍니다. 목록 항목은 아이콘 이름과 아이콘 자체 사이의 연관(associations)이며, 목록에 표시된 텍스트는 아이콘 이름이고, 목록에 표시된 아이콘은 아이콘 그 자체입니다. 또한 항목의 이름에 따라 알파벳순으로 항목을 정렬합니다.

 | iconList |
 iconList := IconListModel new.
 iconList
	items: Smalltalk ui icons icons associations;
	displayBlock: [ :assoc | assoc key];
	sortingBlock: [ :assocA :assocB | assocA key < assocB key ];
	icons: [ :assoc | assoc value ];
	title: 'Availiable icons for the current theme.'.
 iconList openWithSpec


그림 2-3 아이콘 목록의 스크린 샷


ListModel API 뒤에 따라오는 메시지에 주목해야 합니다:

  • displayBlock: 메시지는 도메인 특유의 항목을 수신하고 문자열처럼 목록에 표시 될 수있는 내용을 반환하는 블록을 사용합니다.
  • sortingBlock: 메시지는 목록을 표시하기 전에 목록의 요소를 정렬하는 작업에 사용될 블록을 이용합니다.


결론

이 장에서는 Spec 사용자 인터페이스에 대한 첫번째 접근을 제공했습니다. 먼저 Spec 을 사용해서 사용자 인터페이스를 작성하는 단계와, 기존 Spec 위젯을 구성하는 방법에 대한 두 가지 예제를 확인할 수 있었습니다.


Spec 사용자 인터페이스의 더 많은 예제는 Pharo 이미지 자체에서 찾을 수 있습니다. 모든 Spec 사용자 인터페이스는 ComposableModel 의 하위 클래스이므로 찾기 쉬우며, 각각의 예제 사용자 인터페이스는 예제로 사용될 수 있습니다. 또한 모든 위젯은 독립 실행 형 창으로 열 수 있으며, 설정 메소드는 API 프로토콜로서 분류되기 때문에 위젯 및 사용자 인터페이스에 대한 실험을 쉽게 실험해볼 수 있습니다.


Spec 위젯의 재사용에 대해서는 다음 장(chapter)을 읽는 것이 좋습니다. Spec 위젯의 핵심입니다. 다음장을 통해 얻게될 지식을 사용해서 재사용을 통해 UI를 빠르게 작성하고, 자신의 UI를 다시 사용할 수 있도록 도와줍니다. Spec 의 세 가지 주춧돌(pillars) 대한 그 이후의 장은 Spec 의 기능에 대해서 보다 완전한 개요를 제공하며, 반드시 전부를 읽어볼 가치가 있습니다. 이후의 내용들은 특정 문제 또는 사용 사례에 대한 참조 자료로 더 많이 쓰일 수도 있지만, 전체적으로 읽어두는것을 권장합니다.


Notes

  1. Smalltalk 은 class 측면과 instance 측면의 2가지 측면(side)으로 메서드를 가질 수 있습니다. 이는 다른 언어에서 "클래스 메서드" 라고 불리는것과 같습니다