- Spot은 Go에서 크로스플랫폼 데스크톱 GUI를 만들기 위한 단순한 반응형 툴킷이며, 가능한 경우 네이티브 위젯을 사용하고 플랫폼별 API를 일관되게 제공함
- 애플리케이션 상태가 바뀌면 불변 컴포넌트 트리를 다시 만들고 이전 상태와 비교해 업데이트할 UI 컨트롤을 결정하는 방식으로 동작함
- 현재 백엔드는 macOS의 Cocoa와 그 외 플랫폼의 FLTK 기반 구현이며, macOS에서도 선택적으로 FLTK를 사용할 수 있음
spot은 반응형 모델과 렌더링을 제공하는 백엔드 비의존 코어 패키지이고,spot/ui는 미리 만들어진 크로스플랫폼 GUI 컨트롤 모음임- 자동 레이아웃, 여러 창, 모달 대화상자, 크기 조절 창, 메뉴 바, 커스텀 위젯, 네이티브 위젯 접근, 드래그 앤 드롭, 국제화는 아직 제공하지 않음
Spot의 목적과 기본 모델
- Spot은 Go용 반응형 GUI 툴킷으로, 네이티브 위젯을 가능한 곳에서 사용하면서 여러 플랫폼에서 일관된 API를 제공하도록 설계됨
- 프로젝트에 단순 의존성으로 추가해 Go 코드만 작성하면, 추가 도구나 코드 생성 없이 자체 포함 네이티브 GUI 바이너리를 만들 수 있음
- 예제는
ui.Init(),spot.MountFn(...),ui.Run()흐름으로 창과 버튼을 만들고,spot.UseState[int](<https://github.com/roblillack/ctx, 0>)로 클릭 횟수 상태를 관리함 - 버튼 클릭 핸들러는
setCounter(counter + 1)를 호출하고, 상태가 바뀌면 버튼 제목이"Clicked %d times!"형식으로 바뀜
반응형 업데이트 방식
- Spot에서 reactive는 애플리케이션 상태가 바뀔 때 UI가 자동으로 갱신된다는 뜻임
- 상태 변경 시 불변 컴포넌트 트리를 다시 만들고, 이전 상태와 빠르게 비교해 어떤 UI 컨트롤을 업데이트할지 결정함
- 웹에서 이 아이디어는 흔히 virtual DOM이라고 불리며, Spot은 이 개념을 Go 데스크톱 환경에 가져와 React와 비슷한 GUI 라이브러리를 구현하는 실험에서 시작됨
- 개발자는 UI를 수동으로 업데이트하는 대신, 부작용 없는 렌더링 함수와
UseState같은 훅으로 애플리케이션 로직과 상태를 관리함
백엔드와 패키지 구성
- Spot은 컴파일 시 실행 플랫폼에 맞는 백엔드를 자동 선택함
- 현재 제공되는 백엔드는 두 가지임
- macOS에서는 Cocoa 백엔드를 사용하고, 그 외 플랫폼에서는 FLTK 기반 백엔드를 사용함
- macOS에서도 선택적으로 FLTK를 사용할 수 있으며, Windows 지원 개선은 향후 계획으로 남아 있음
spot은 반응형 모델과 렌더링 기능을 제공하는 코어 패키지이며,spot.Control인터페이스를 구현하는 어떤 컨트롤 집합과도 사용할 수 있음spot/ui는 Spot과 함께 사용할 수 있는 미리 만들어진 크로스플랫폼 GUI 컨트롤 패키지임
컴포넌트, 컨트롤, 훅
- React처럼 커스텀 훅을 만들 수 있음
- 첫 번째 인자로
*spot.RenderContext를 받는 함수를 만들고spot.UseState,spot.UseEffect등을 호출해 Spot 생명주기에 연결함 - 관례적으로 함수 이름은
Use…접두사를 붙임
- 첫 번째 인자로
- 커스텀 컴포넌트는
spot.Component인터페이스를 구현하는 구조체로 만들 수 있음- 이 인터페이스는
Render(ctx *spot.RenderContext) spot.Component단일 메서드를 가짐 - 이렇게 만든 컴포넌트는 내장 컴포넌트와 같은 방식으로 사용할 수 있음
- 이 인터페이스는
- Spot에서 component는 비즈니스 로직과 상태를 담는 논리 단위임
- 컴포넌트는 다른 컴포넌트로 구성되며, 최종적으로 하나 이상의 컨트롤로 렌더링됨
- control은 UI 트리에 마운트되는 특수한 컴포넌트이며, 화면의 시각 요소를 나타냄
- 일반적으로 버튼, 라벨, 텍스트 입력처럼 GUI 백엔드의 네이티브 구현을 기반으로 함
- 제공된 위젯 라이브러리와 완전히 다른 위젯 라이브러리도 사용할 수 있음
spot.Component인터페이스를 구현하고 네이티브 위젯을 관리하는 구조체를 만들면 됨
spot/ui를 Cocoa나 FLTK 이외의 백엔드와 함께 쓰는 것은 현재 지원되지 않음
렌더링 생명주기 용어
- Make:
spot.Component인터페이스를 구현하는 구조체 인스턴스를 만들거나, 렌더 함수와 함께spot.Make를 호출해 새 컴포넌트 인스턴스를 만드는 과정 - Render: 컴포넌트 상태를 구성 요소에 적용하고 다른 컴포넌트 인스턴스를 반환하는 과정
- Build: 컴포넌트를 재귀적으로 렌더링해 컨트롤 트리를 만드는 과정
spot.Build에 컴포넌트 인스턴스를 넘기거나,spot.BuildFn에 렌더 함수를 넘겨 실행함
- Mount: 가상 컨트롤 트리에서 실제 UI 컨트롤을 만드는 과정
- 트리 노드의
Mount를 호출하거나,spot.Mount,spot.MountFn을 사용할 수 있음
- 트리 노드의
- Update: 마운트된 컨트롤 트리를 업데이트하는 과정
- 트리 노드의
Update를 호출해 수행함
- 트리 노드의
현재 제공하지 않는 기능
- Spot은 현재 다음 기능을 제공하지 않음
-
자동 레이아웃
- 여러 창
- 모달 대화상자
- 크기 조절 가능한 창
- 메뉴 바
- 커스텀 위젯
- 네이티브 위젯 접근
- 드래그 앤 드롭
- 국제화
-
지원 UI 컨트롤
- Spot은 버튼, 라벨, 텍스트 입력, 슬라이더, 드롭다운 등 여러 UI 컨트롤을 기본 제공함
- 지원 상태 표기는 ❓ 미구현, 🚧 작업 중, ⚠️ 부분 구현, ✅ 완료로 나뉨
- 완료된 주요 컨트롤은 다음과 같음
- Button: 단순 액션 실행 버튼,
Fl_Button과NSButton사용 - Checkbox: 두 선택지 중 하나를 고르는 컨트롤,
Fl_Check_Button과NSButton사용 - Dropdown: 여러 항목 중 하나를 고르는 드롭다운,
Fl_Choice와NSComboBox사용 - Image: 비트맵 이미지 표시 컨트롤,
Fl_Box와 커스텀NSButton사용 - Label: 편집 불가 텍스트 라벨,
Fl_Box와NSTextField사용 - ListBox: 단일 또는 다중 선택 목록 컨트롤,
Fl_Select_Browser/Fl_Multi_Browser와NSTableView사용 - ProgressBar: 장기 작업 진행률 표시,
Fl_Progress와NSProgressIndicator사용 - Slider: 수평 슬라이더 입력,
Fl_Slider와NSSlider사용 - Spinner: 위/아래 버튼이 있는 숫자 입력,
Fl_Spinner와NSTextField+NSStepper사용 - TextField: 한 줄 텍스트 입력,
Fl_Input과NSTextField사용 - TextEditor: 여러 줄 텍스트 편집,
Fl_Text_Editor와NSTextView사용 - Window: 최상위 창 컨트롤,
Fl_Window과NSWindow사용
- Button: 단순 액션 실행 버튼,
- 부분 구현 또는 미구현 컨트롤도 있음
- Dial: 원형 상태 컨트롤이며 ⚠️ 부분 구현 상태
- ComboBox: 텍스트 입력이 결합된 드롭다운 메뉴이며 아직 시작되지 않음
- 잠재적 향후 백엔드 후보로 네이티브 Windows 컨트롤 라이브러리
https://github.com/rodrigocfd/windigo가 제시됨