compose-rust 가이드

레퍼런스

위젯 레퍼런스

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안의 글을 선택하고 복사할 수 있게 합니다.
컨트롤ButtonFilled, 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등록한 에셋의 이미지, 역할로 고르는 아이콘.
CanvasDrawList 값으로 그리는 커스텀 드로잉. 같은 목록 둘은 아무것도 보내지 않습니다.

Modifier

Compose에서 Modifier 는 어느 composable에나 붙고, 여기서도 같습니다. 모든 위젯이 모든 Modifier를 받으며, Text 와 Spacer 도 예외가 아닙니다. 와이어에서 Modifier 목록은 고정 크기 값의 나열이고, 렌더러가 이것을 Compose Modifier 체인으로 다시 만듭니다.

Modifier값효과
Weightf32Row 나 Column 안에서 주축의 남은 공간을 나눠 갖는 몫.
FillMaxWidth, FillMaxHeight없음쓸 수 있는 너비나 높이를 모두 차지합니다.
Width, Height, Sizedp고정 크기.
Padding, PaddingEachdp직접 정한 안쪽 여백. 네 변 같게, 또는 변마다.
PaddingRoleSpaceRole디자인 시스템이 정한 안쪽 여백. 이쪽을 권합니다.
BackgroundPaint위젯 뒤의 채움.
Shape모서리마다 dp직접 정한 모서리 둥글기.
ShapeRoleShapeRole디자인 시스템이 정한 모서리 둥글기.
Borderdp와 Paint두께와 색을 가진 테두리.
Elevationdp떠 있는 높이. 디자인 시스템마다 자기 방식으로 그립니다.
MaterialMaterialRole유리처럼 표면이 무엇으로 만들어졌는지. 디자인 시스템이 풉니다.
MotionMotionRole이 위젯 자신의 전환에 쓰는 디자인 시스템의 타이밍.
Clickable핸들러 id어느 위젯이든 클릭을 알리게 합니다.
ObserveSize토큰이 노드의 잰 크기를 앱이 고른 토큰으로 알려 달라고 렌더러에 요청합니다. node_size 로 읽습니다.

설정하지 않은 것은 0이 아닙니다. 쓰지 않은 Modifier는 아무것도 보내지 않습니다. 여백이 없는 것과 여백 0은 화면에서 같아 보이지만, 레코드 비용이 들어야 하는 것은 둘 중 하나뿐입니다.

역할 어휘

위젯은 리터럴이 아니라 역할을 내보냅니다. 역할은 일의 이름("강조색", "제목 단", "중간 모서리")이고, 렌더러가 활성 디자인 시스템에 맞춰 풉니다. 그래서 같은 트리가 어떤 기계에서는 Material 3로, 다른 기계에서는 Liquid Glass로 나옵니다. 시스템을 고르는 방법은 디자인 시스템에 있습니다. 아래 타입은 모두 0.0.1에 있습니다.

Paint와 Color

색을 받는 곳의 타입은 모두 Paint 입니다. 역할, 리터럴 ARGB 값, 또는 그라디언트 같은 등록된 브러시 중 하나입니다.

rust, 0.0.1에서 컴파일됨
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로 나옵니다.

배치와 텍스트 열거형

열거형값쓰는 곳
ArrangementStart, Center, End, SpaceBetween, SpaceAround, SpaceEvenlyRow 와 Column 의 주축
AlignmentTopStart 부터 BottomEnd 까지 아홉 개Row 와 Column 의 교차축, Box 의 두 축
TextAlignStart, Center, End, JustifyText
TextOverflowClip, Ellipsis, Visible줄 수 제한이 있는 Text
ButtonVariantFilled, Tonal, Outlined, TextButton
MessageDurationShort, Long잠깐 뜨는 메시지

창 크기

UI는 Rust가 기술하고 렌더러가 잽니다. 그래서 Rust가 창 너비를 아는 길은 렌더러가 알려 주는 것 하나뿐입니다. window_size() 는 width_dp, height_dp, class 와 is_compact(), is_medium(), is_expanded() 를 가진 WindowSize 를 돌려줍니다. 0.0.1에 있습니다.

클래스너비모양
WindowSizeClass::Compact600 dp 미만폰 모양. 한 열.
WindowSizeClass::Medium600~840 dp태블릿 모양.
WindowSizeClass::Expanded840 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부터 시작하므로, 나중에 더해지는 핵심 위젯과 겹치지 않습니다.