TheSpecUIframework:Chapter 05
- 레이아웃 구성
레이아웃 구성
컨테이너의 크기 조정에 위젯의 동작을 배치하고 설명하는 것은, 중요하지만 복잡한 문제입니다. 이 장에서는 Spec 을 사용해서 레이아웃을 표현하는 다양한 방법을 제시합니다.
레이아웃 정보
창이나 UI 의 재사용에서 위젯을 배치하는 것은 중요한 문제입니다. 위젯이 컨테이너에 배치 되어야할 위치를 결정할 때 많은 요인이 작용하기 때문입니다(컨테이너는 창 또는 다른 위젯일 수 있습니다).
간단한 해결책은 바깥쪽에서 둘러싸는 컨테이너의 절대 좌표에 위젯을 배치하는 것이지만, 컨테이너 크기를 조정한다면 동작은 중단되어 버립니다: 절대 좌표를 사용한다면 위젯은 컨테이너와 함께 커지거나 줄어들지 않기 때문입니다. 하지만 절대 좌표로 위치를 지정해도 창 크기를 조정하지 않으면 문제는 되지 않으며, 픽셀단위로 모든 위젯을 완벽하게 배치할 수 있습니다.
여러 가지로 사용될 수 있기 때문에, 배치할 위젯은 여러가지 방법으로 제공되어야 합니다. Spec 은 레이아웃을 수행하는 다양한 옵션을 제공하며 SpecLayout 클래스의 commands 프로토콜에서 메서드를 확인할 수 있습니다. 지금까지는, 레이아웃에서 순서에따라 행과 열만 사용하며 컨테이너에 하나의 위젯을 추가하는 것을 보았습니다. 또한 이 모든 결과에서 행, 열 또는 단일 위젯은 컨테이너에서 항상 사용 가능한 모든 공간을 차지합니다. 이는 기본적인 동작입니다.
SpecLayout 의 add: 메소드는 하나의 위젯만 추가하도록 허용하기 때문에, 사용자 인터페이스에 둘 이상의 위젯이 필요하면 이 장에서 제시하는 레이아웃 중 하나를 지정해야 합니다. 여기서는 위젯을 배치하기위한 두 가지 광범위한 전략(먼저 행과 열을 지정하는 다양한 옵션과 두 번째로 위젯을 자유롭게 배치 할 수 있도록 다양하게 제공되는 방법)에 대해 깊이 논의합니다.이 방법들은 생성되는 UI 의 종류에 따라 각각은 장점과 단점을 갖고 있으므로 절충안을 만들 수 있을만큼 잘 알고있는 것이 가장 좋습니다.
사용할 수 있는 예제
이러한 레이아웃을 설명하기 위해 우리는 두 개의 버튼, 목록 및 텍스트 필드가있는 예제 클래스를 사용합니다. non-layout 코드는 아래에 있습니다
ComposableModel subclass: #LayoutExample
instanceVariableNames: 'list button button2 text'
classVariableNames: ''
package: 'Spec-BuildUIWithSpec'
LayoutExample >> initializeWidgets
button := self newButton.
button2 := self newButton.
list := self newList.
text := self newText.
button label: 'i am a button'.
button label: 'me too!'.
행 및 열 레이아웃
간단하고 자주 사용되는 레이아웃 종류중에 두 개 이상의 위젯을 갖는 경우라면, 위젯을 행이나 열에 정렬하는 경우입니다. Spec 은 SpecLayout 클래스의 newRow: 및 newColumn: 메시지를 사용해서, 설명한 레이아웃을 쉽게 지정할 수있는 방법을 제공합니다. 이 메시지들은 위젯에 주어진 공간 내에서 고르게 분포 된 행이나 열을 각각 만듭니다.
예를 들어, 다음의 코드는 목록의 버튼과 행의 버튼을 배치합니다:
LayoutExample >> oneRow
^ SpecLayout composed
newRow: [ :row | row add: #list; add: #button ];
yourself
위의 코드는 newRow: 메시지를 사용하여 위젯 행을 만드는 레이아웃 메서드입니다. 메시지의 인수는 하나의 인수로 된 블록이며, 블록 인수는 SpecRowLayout 의 인스턴스를 포함합니다. 그런 다음 위젯이 이 레이아웃 객체에 추가되어 행을 모두 정렬합니다.
아래의 코드는 이러한 레이아웃 명세를 가진 예제를 보여주며, 그 결과 UI는 그림 5-1과 같다. title: 메시지는 별도의 설명조차 필요없다.
| le |
le := LayoutExample new.
le title: 'RowOfWidgets'.
le openWithSpec: #oneRow
위젯을 열로 렌더링하면 newRow: 메시지 대신 newColumn 메시지가 사용됩니다. 이 메시지는 인수가 하나 인 블록을 사용하며, 블록 인수는 SpecColumnLayout 의 인스턴스를 포함합니다.
LayoutExample >> oneColumn
^ SpecLayout composed
newColumn: [ :col | col add: #list; add: #button ];
yourself
아래 코드를 실행하면 그림 5-1 의 결과가 됩니다. 간략하게 보여드리지만, 이 장의 나머지 부분에서는 UI 실행하는 코드를 더 이상 포함하지 않을 것입니다.
| le |
le := LayoutExample new.
le title: 'ColumnOfWidgets'.
le openWithSpec: #oneColumn.
Spec 은 SpecLayout 대신 SpecRowLayout 및 SpecColumnLayout 을 직접 사용할 수도 있습니다. 앞의 코드는 oneRow 및 oneColumn 레이아웃 메서드를 보다 간결하게 만들어 줍니다.
LayoutExample >> oneRowConcise
^ SpecRowLayout composed
add: #list; add: #button;
yourself.
LayoutExample >> oneColumnConcise
^ SpecColumnLayout composed
add: #list; add: #button;
yourself
행과 열을 결합하기
newRow: 및 newColumn: 메시지를 서로 다른 조합으로 보내서 행과 열을 결합하면, 보다 복잡한 레이아웃을 만들 수 있습니다. 여기서는 가능성을 설명하기 위해 여기에 몇 가지 예를 보여드리겠습니다.
첫 번째 예제는 두 행의 위젯을 가질 수 있는 방법을 보여줍니다. 여기서는 열을 만들고 두 번 newRow: 를 호출합니다. 결과는 그림 5-3과 같습니다.
LayoutExample >> twoRows
^ SpecColumnLayout composed
newRow: [ :row | row add: #text ];
newRow: [ :row | row add: #button; add: #button2 ];
yourself
여러 행을 가지려면 SpecColumnLayout 에 추가해야하며, 여러 열을 가지려면 SpecRowLayout 에 추가해야 합니다. SpecComposedLayout 에 addRow: 또는 addColumn: 을 여러 번 보내는 것은 마지막 행 resp 만 생성합니다. |
행과 열은 물론 다중 중첩 될 수도 있습니다. 예를 들어 "SpecRowLayout"에 중첩된 열에 중첩된 행에 두 개의 버튼을 추가합니다. 결과 UI 가 그림 5-2에 나와 있습니다.
LayoutExample >> nesting1
^ SpecRowLayout composed
newColumn: [ :col | col add: #list];
newColumn: [ :col |
col
add: #text;
newRow: [ :row |
row
add: #button;
add: #button2]
];
yourself