레퍼런스
위젯 레퍼런스
compose-rust 스키마의 위젯, Modifier, 역할 전부입니다. 스키마는 닫혀 있습니다. 렌더러는 정확히
이 목록만 해석하고 다른 것은 해석하지 않습니다. 모르는 위젯 종류를 받으면 충돌하지 않고
ProtocolError 이벤트를 냅니다.
아래 위젯 전부의 스키마와 렌더러 쪽 구현은 0.0.1에 있습니다
구현. 그것을 내보내려고 부르는 Rust 함수,
Column(...) 이나 Text(...) 같은 것은 1.0.0의 작성 API와 함께
들어옵니다 계획. 작성 API는 자기 위젯을 더하지 않으므로, 이
페이지가 곧 앞으로 쓸 목록입니다.
위젯
이름은 Compose의 것입니다. 위젯마다 WidgetKind 에 고정된 태그가 있고, Kotlin
인터프리터에는 위젯마다 그리는 함수가 하나씩 있습니다.
| 묶음 | 위젯 | 무엇인가 |
|---|---|---|
| 배치 | Column, Row | 한 축을 따라 놓는 자식들. 주축에는 배열, 교차축에는 정렬을 줍니다. |
Box | 서로 겹쳐 놓는 자식들. 두 축 모두 정렬합니다. | |
ScrollColumn, ScrollRow | 스크롤되는 열이나 행. 자식마다 실제 노드가 되므로, 긴 목록에는 lazy 위젯을 씁니다. | |
Spacer | 빈 공간. 보통 weight 나 고정 크기로 크기를 정합니다. | |
SplitPane | 사용자가 끌거나 키보드로 옮기는 구분선을 가진 두 창. | |
Scaffold, ScaffoldSlot | 화면의 틀: 바, 페이지, 플로팅 액션. 앱이 채운 칸을 렌더러가 창 너비에 맞게 배치합니다. | |
FileDropTarget | 시스템에서 끌어다 놓은 파일을 받아 경로를 알리는 영역. | |
| 텍스트와 입력 | Text | 타입 역할, 색, 정렬, 줄 수 제한, 넘침을 갖는 글. 스타일이 다른 구간을 싣고, 스트리밍으로 뒷부분을 이어 받을 수 있습니다. |
TextField | 비제어 텍스트 입력. 편집 버퍼와 IME 조합은 렌더러에 머뭅니다. | |
SelectionContainer | 안의 글을 선택하고 복사할 수 있게 합니다. | |
| 컨트롤 | Button | Filled, Tonal, Outlined, Text 네 변형 중 하나의 버튼. |
Checkbox, RadioButton, Switch | 완전히 제어되는 토글. 보낸 값이 그대로 그려집니다. | |
Slider | 범위 안의 값. 끄는 동안의 위치는 렌더러가 갖습니다. | |
Dropdown | 팝업에서 고르는 선택지. | |
DatePicker, TimePicker | 날짜와 시간 선택기. 고르는 화면, 로캘, 형식은 렌더러가 갖습니다. | |
Chip | 작은 선택지나 필터. 받은 선택 상태를 그대로 그리고, 자기 상태를 갖지 않습니다. | |
ProgressIndicator | 정해진 진행률이나 정해지지 않은 진행. | |
| 컨테이너 | Card, Surface | 모양, 높이, 재질을 디자인 시스템에서 받는 채워진 패널. |
TopAppBar | 제목과 동작을 가진 화면 상단 바. | |
Divider | 묶음 사이의 가는 선. | |
Tooltip, Badge | 마우스를 올리거나 길게 누를 때의 힌트, 다른 위젯에 붙는 표시. | |
FloatingAction | 화면의 중심이 되는 동작 하나. 모양과 자리는 디자인 시스템이 정합니다. | |
| 목록 | LazyColumn, LazyRow | 윈도잉 목록. 렌더러가 보이는 범위를 요청하고 Host는 그 범위만 만듭니다. 목록과 스트리밍을 보십시오. |
LazyGrid | 같은 약속을 따르는 윈도잉 격자. | |
LinearProgressIndicator | 확장 위젯의 예제(태그 100). 확장을 보십시오. | |
| 탐색 | Navigation, NavigationItem | 목적지 묶음. 렌더러가 잰 너비에 따라 바, 레일, 서랍으로 그립니다. |
Tabs | 페이지 위쪽의 탭. | |
| 오버레이 | Dialog, Menu, Sheet | 페이지 위에 뜨는 내용. 시트가 들어오는 가장자리와 열리고 닫히는 동작은 렌더러가 정합니다. |
| 메시지 | 잠깐 뜨는 메시지는 트리에 속하지 않습니다. show_message 와 Message 가 보내며, 0.0.1에 있습니다. | |
| 그림 | Image, Icon | 등록한 에셋의 이미지, 역할로 고르는 아이콘. |
Canvas | DrawList 값으로 그리는 커스텀 드로잉. 같은 목록 둘은 아무것도 보내지 않습니다. |
Modifier
Compose에서 Modifier 는 어느 composable에나 붙고, 여기서도 같습니다. 모든 위젯이
모든 Modifier를 받으며, Text 와 Spacer 도 예외가 아닙니다. 와이어에서
Modifier 목록은 고정 크기 값의 나열이고, 렌더러가 이것을 Compose Modifier 체인으로
다시 만듭니다.
| Modifier | 값 | 효과 |
|---|---|---|
Weight | f32 | Row 나 Column 안에서 주축의 남은 공간을 나눠 갖는 몫. |
FillMaxWidth, FillMaxHeight | 없음 | 쓸 수 있는 너비나 높이를 모두 차지합니다. |
Width, Height, Size | dp | 고정 크기. |
Padding, PaddingEach | dp | 직접 정한 안쪽 여백. 네 변 같게, 또는 변마다. |
PaddingRole | SpaceRole | 디자인 시스템이 정한 안쪽 여백. 이쪽을 권합니다. |
Background | Paint | 위젯 뒤의 채움. |
Shape | 모서리마다 dp | 직접 정한 모서리 둥글기. |
ShapeRole | ShapeRole | 디자인 시스템이 정한 모서리 둥글기. |
Border | dp와 Paint | 두께와 색을 가진 테두리. |
Elevation | dp | 떠 있는 높이. 디자인 시스템마다 자기 방식으로 그립니다. |
Material | MaterialRole | 유리처럼 표면이 무엇으로 만들어졌는지. 디자인 시스템이 풉니다. |
Motion | MotionRole | 이 위젯 자신의 전환에 쓰는 디자인 시스템의 타이밍. |
Clickable | 핸들러 id | 어느 위젯이든 클릭을 알리게 합니다. |
ObserveSize | 토큰 | 이 노드의 잰 크기를 앱이 고른 토큰으로 알려 달라고 렌더러에 요청합니다. node_size 로 읽습니다. |
설정하지 않은 것은 0이 아닙니다. 쓰지 않은 Modifier는 아무것도 보내지 않습니다. 여백이 없는 것과 여백 0은 화면에서 같아 보이지만, 레코드 비용이 들어야 하는 것은 둘 중 하나뿐입니다.
역할 어휘
위젯은 리터럴이 아니라 역할을 내보냅니다. 역할은 일의 이름("강조색", "제목 단", "중간 모서리")이고, 렌더러가 활성 디자인 시스템에 맞춰 풉니다. 그래서 같은 트리가 어떤 기계에서는 Material 3로, 다른 기계에서는 Liquid Glass로 나옵니다. 시스템을 고르는 방법은 디자인 시스템에 있습니다. 아래 타입은 모두 0.0.1에 있습니다.
Paint와 Color
색을 받는 곳의 타입은 모두 Paint 입니다. 역할, 리터럴 ARGB 값, 또는 그라디언트
같은 등록된 브러시 중 하나입니다.
use compose_rust::{Color, ColorRole, Paint};
let accent = Paint::Role(ColorRole::Primary); // resolved by the design system
let brand = Paint::Literal(Color::rgb(0x1b6ef3)); // opaque, 0xRRGGBB
let veil = Paint::Literal(Color::argb(0x80ff0000)); // 0xAARRGGBB
리터럴은 탈출구입니다. 디자인 시스템이 바뀌어도 그대로 남습니다. 브랜드 색처럼 그것이 바라는
바일 때도 있지만, 밝은 페이지에서 보이고 어두운 페이지에서 사라지는 색처럼 대개는 아닙니다.
브랜드 색에는 Palette 가 낫습니다. 앱 색을
보십시오.
ColorRole: 역할 45개
잉크를 가리키는 역할은 모두 그 잉크가 놓일 표면과 짝을 이룹니다. OnPrimary 는
Primary 로 채운 것 위의 잉크이고, 나머지도 같습니다.
| 묶음 | 역할 | 쓰임 |
|---|---|---|
| 강조 | Primary, OnPrimary, Secondary, OnSecondary, Tertiary, OnTertiary | 세 강조색: 눈이 첫째, 둘째, 셋째로 가는 곳. |
| 페이지 | Background, OnBackground | 페이지 자체와 그 위의 잉크. |
| 표면 | Surface, OnSurface, SurfaceVariant, OnSurfaceVariant, SurfaceContainer | 읽는 표면. OnSurfaceVariant 는 흐린 잉크로, 캡션과 레이블에 씁니다. |
| 컨테이너 | PrimaryContainer, OnPrimaryContainer, SecondaryContainer, OnSecondaryContainer, TertiaryContainer, OnTertiaryContainer | 강조색의 친척으로 읽히는 차분한 채움. 저마다 자기 잉크가 있습니다. |
| 선 | Outline, OutlineVariant | 테두리와 가는 선, 진한 것과 옅은 것. |
| 오류 | Error, OnError | 잘못된 것, 그리고 되돌릴 수 없는 동작의 레이블. |
| 코드 | SyntaxKeyword, SyntaxString, SyntaxComment 를 비롯한 문법 역할, 그리고 DiffAdded, DiffRemoved, DiffModified 와 그 컨테이너, 강조 | 코드를 칠하는 역할 22개. 시스템마다 자기 플랫폼의 코드 편집기에서 답을 가져오고, 문법 잉크는 모두 SurfaceContainer 위에서 4.5:1로 읽힙니다. |
패널이 페이지와 구별되어야 하면 SurfaceContainer 를 씁니다.
Material 3는 일부러 Surface 와 Background 에 같은 값을 주고, 깊이는
톤이 다른 컨테이너로 나타냅니다. Background 페이지 위에 Surface 로
채운 패널은 맞는 색으로 그려지지만 보이지 않습니다. 지원하는 디자인 시스템은 모두
SurfaceContainer 를 페이지와 구별되게 만듭니다.
TypeRole: 아홉 단
| 단 | 쓰임 |
|---|---|
Display | 화면에서 가장 큰 것. 한 번만 씁니다. |
Headline | 화면의 제목. |
Title | 구역의 제목, 바의 제목. |
Subtitle | 제목 아래 줄. |
Body | 본문. 기본 단입니다. |
BodyStrong | 무게가 실려야 하는 본문. |
Label | 버튼 글자, 칩, 입력 레이블. |
Caption | 읽을 수 있는 가장 작은 단: 시각, 각주. |
Mono | 고정폭: 코드, 경로, 줄을 맞춰야 하는 숫자. |
ShapeRole, SpaceRole, MotionRole
ShapeRole 은 None, ExtraSmall, Small,
Medium, Large, Full 입니다. 반지름은 디자인 시스템이
정하고, Full 은 캡슐 모양입니다.
SpaceRole 은 None, Xs, Sm,
Md, Lg, Xl, Xxl 입니다. 밀도는 디자인
시스템마다 다르므로, 간격을 dp 숫자가 아니라 역할로 쓰는 것입니다.
MotionRole 은 Instant, Quick, Standard,
Slow, Emphasized 입니다. 디자인 시스템마다 자기 길이와 곡선을 줍니다.
IconRole
아이콘은 플랫폼 아이콘 이름이 아니라 쓰임으로 고릅니다. Back,
Forward, Close, Search, Add,
Check, Settings, More, Home,
List, Inbox, Menu, History 입니다. 역할이기
때문에 같은 선언이 Apple의 시스템에서는 SF Symbol로, Material 3에서는 Material Symbol로
나옵니다.
배치와 텍스트 열거형
| 열거형 | 값 | 쓰는 곳 |
|---|---|---|
Arrangement | Start, Center, End, SpaceBetween, SpaceAround, SpaceEvenly | Row 와 Column 의 주축 |
Alignment | TopStart 부터 BottomEnd 까지 아홉 개 | Row 와 Column 의 교차축, Box 의 두 축 |
TextAlign | Start, Center, End, Justify | Text |
TextOverflow | Clip, Ellipsis, Visible | 줄 수 제한이 있는 Text |
ButtonVariant | Filled, Tonal, Outlined, Text | Button |
MessageDuration | Short, Long | 잠깐 뜨는 메시지 |
창 크기
UI는 Rust가 기술하고 렌더러가 잽니다. 그래서 Rust가 창 너비를 아는 길은 렌더러가 알려 주는 것
하나뿐입니다. window_size() 는 width_dp, height_dp,
class 와 is_compact(), is_medium(),
is_expanded() 를 가진 WindowSize 를 돌려줍니다. 0.0.1에 있습니다.
| 클래스 | 너비 | 모양 |
|---|---|---|
WindowSizeClass::Compact | 600 dp 미만 | 폰 모양. 한 열. |
WindowSizeClass::Medium | 600~840 dp | 태블릿 모양. |
WindowSizeClass::Expanded | 840 dp 이상 | 데스크톱 모양. 늘 열린 사이드바를 둘 자리가 있습니다. |
클래스가 바뀔 때만 알립니다. 렌더러는 클래스가 바뀔 때 이벤트를 한 번 보내고
그 사이에는 아무것도 보내지 않습니다. 창을 700 dp에서 800 dp로 끌어도 Rust에서는 아무것도
깨어나지 않습니다. 레이아웃마다 바뀌는 크기를 알리면 레이아웃마다 Rust 코드가 돌기 때문입니다.
처음 재기 전에는 0 × 0의 Compact 입니다. 한 열 배치는 어느 너비에서나 쓸 수 있기
때문입니다.
Navigation, Sheet, Scaffold 는 렌더러가 이미 가진 노드를
옮겨서 스스로 적응합니다. 창 크기는 위젯이 대신 정해 줄 수 없는 결정, 예를 들어 한 열 대신 두
열로 놓는 데 씁니다.
위젯마다 상태를 두는 곳
애플리케이션 상태는 사용자의 것이고, UI 로컬 상태는 렌더러의 것입니다. 아래는 사람들이 놀라는 곳입니다. 제어되는 것처럼 보이는데 아니거나, 그 반대인 위젯입니다.
| 위젯 | 렌더러가 갖는 것 | Rust가 보내는 것 |
|---|---|---|
TextField | 편집 버퍼 전체, 선택 영역, IME 조합 | 값은 없습니다. 변화는 이벤트로 오고, SetText 는 조합이 끝난 뒤에 텍스트를 바꿉니다. |
Dialog, Sheet, Menu | 열림 상태, 열리고 닫히는 애니메이션 | 시작값이 되고 바깥의 변화를 전하는 열림 플래그. |
Dropdown | 팝업이 열려 있는지 | 선택된 인덱스뿐. |
Navigation, Tabs | 어느 것이 표시되었는지, 그 사이의 이동 | 시작값이 되는 선택된 인덱스. |
Slider | 끄는 동안 지나는 위치 | 시작값이 되고 바깥에서 옮기는 값. |
ScrollColumn, ScrollRow, lazy 위젯 | 스크롤 위치, 미리 읽는 버퍼 | 항목 수와 요청된 범위의 항목. |
Checkbox, RadioButton, Switch, Chip | 없음. 완전히 제어됩니다 | 그대로 그려지는 체크나 선택 상태. |
DatePicker, TimePicker | 고르는 화면, 로캘, 시간대, 형식 | 값과 그 범위. |
| 모든 위젯 | 포커스, 호버, 누름 반응, 애니메이션 진행 | 없음. |
확장
확장은 컴파일 시점의 소스 파일 한 쌍, 곧 Rust 파일 하나와 Kotlin 파일 하나이고 두 쪽에 함께
빌드됩니다. 런타임 플러그인이 아닙니다. 배포된 렌더러는 새 위젯을 불러올 수 없습니다. 스키마
해시가 더는 맞지 않기 때문입니다. 크레이트에는 예제 하나, progress: f32 속성 하나를
가진 LinearProgressIndicator 가 있습니다.
직접 더하려면 compose-rust/src/extensions.rs 에 위젯과 속성 태그를 등록하고, 짝이
되는 Kotlin 렌더러에서 새 종류를 그립니다. 확장 위젯 태그는 100부터 시작하므로, 나중에 더해지는
핵심 위젯과 겹치지 않습니다.