263 lines
9.2 KiB
C#
263 lines
9.2 KiB
C#
#nullable enable
|
|
using System;
|
|
using Cysharp.Threading.Tasks;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
using UVC.UIToolkit.Modal;
|
|
|
|
namespace UVC.Sample.UIToolkit
|
|
{
|
|
/// <summary>
|
|
/// UTKColorPicker 샘플 코드
|
|
/// 버튼 클릭으로 컬러 피커를 열고 선택된 색상을 미리보기에 표시
|
|
/// </summary>
|
|
public class UTKColorPickerSample : MonoBehaviour
|
|
{
|
|
[SerializeField] private UIDocument? _uiDocument;
|
|
|
|
private VisualElement? _root;
|
|
private VisualElement? _colorPreview;
|
|
private Label? _colorLabel;
|
|
private Toggle? _useAlphaToggle;
|
|
|
|
private Color _currentColor = Color.blue;
|
|
private UTKColorPicker? _currentPicker;
|
|
|
|
private void Start()
|
|
{
|
|
if (_uiDocument == null)
|
|
{
|
|
Debug.LogError("UIDocument is not assigned!");
|
|
return;
|
|
}
|
|
|
|
_root = _uiDocument.rootVisualElement;
|
|
CreateSampleUI();
|
|
}
|
|
|
|
private void CreateSampleUI()
|
|
{
|
|
if (_root == null) return;
|
|
|
|
// 메인 컨테이너
|
|
var container = new VisualElement();
|
|
container.style.position = Position.Absolute;
|
|
container.style.left = 20;
|
|
container.style.top = 20;
|
|
container.style.backgroundColor = new Color(0.2f, 0.2f, 0.2f);
|
|
container.style.borderTopLeftRadius = 8;
|
|
container.style.borderTopRightRadius = 8;
|
|
container.style.borderBottomLeftRadius = 8;
|
|
container.style.borderBottomRightRadius = 8;
|
|
container.style.paddingTop = 15;
|
|
container.style.paddingBottom = 15;
|
|
container.style.paddingLeft = 15;
|
|
container.style.paddingRight = 15;
|
|
container.style.width = 280;
|
|
|
|
// 타이틀
|
|
var title = new Label("UTKColorPicker Sample");
|
|
title.style.fontSize = 16;
|
|
title.style.unityFontStyleAndWeight = FontStyle.Bold;
|
|
title.style.color = Color.white;
|
|
title.style.marginBottom = 15;
|
|
container.Add(title);
|
|
|
|
// 색상 미리보기 영역
|
|
var previewRow = new VisualElement();
|
|
previewRow.style.flexDirection = FlexDirection.Row;
|
|
previewRow.style.alignItems = Align.Center;
|
|
previewRow.style.marginBottom = 15;
|
|
|
|
var previewLabel = new Label("Current Color:");
|
|
previewLabel.style.color = Color.white;
|
|
previewLabel.style.width = 100;
|
|
previewRow.Add(previewLabel);
|
|
|
|
_colorPreview = new VisualElement();
|
|
_colorPreview.style.width = 60;
|
|
_colorPreview.style.height = 30;
|
|
_colorPreview.style.backgroundColor = _currentColor;
|
|
_colorPreview.style.borderTopLeftRadius = 4;
|
|
_colorPreview.style.borderTopRightRadius = 4;
|
|
_colorPreview.style.borderBottomLeftRadius = 4;
|
|
_colorPreview.style.borderBottomRightRadius = 4;
|
|
_colorPreview.style.borderTopWidth = 1;
|
|
_colorPreview.style.borderBottomWidth = 1;
|
|
_colorPreview.style.borderLeftWidth = 1;
|
|
_colorPreview.style.borderRightWidth = 1;
|
|
_colorPreview.style.borderTopColor = new Color(0.4f, 0.4f, 0.4f);
|
|
_colorPreview.style.borderBottomColor = new Color(0.4f, 0.4f, 0.4f);
|
|
_colorPreview.style.borderLeftColor = new Color(0.4f, 0.4f, 0.4f);
|
|
_colorPreview.style.borderRightColor = new Color(0.4f, 0.4f, 0.4f);
|
|
previewRow.Add(_colorPreview);
|
|
|
|
_colorLabel = new Label(ColorToHex(_currentColor));
|
|
_colorLabel.style.color = new Color(0.7f, 0.7f, 0.7f);
|
|
_colorLabel.style.marginLeft = 10;
|
|
previewRow.Add(_colorLabel);
|
|
|
|
container.Add(previewRow);
|
|
|
|
// Alpha 사용 토글
|
|
var alphaRow = new VisualElement();
|
|
alphaRow.style.flexDirection = FlexDirection.Row;
|
|
alphaRow.style.alignItems = Align.Center;
|
|
alphaRow.style.marginBottom = 15;
|
|
|
|
_useAlphaToggle = new Toggle("Use Alpha Channel");
|
|
_useAlphaToggle.value = true;
|
|
_useAlphaToggle.style.color = Color.white;
|
|
alphaRow.Add(_useAlphaToggle);
|
|
|
|
container.Add(alphaRow);
|
|
|
|
// 버튼
|
|
var openPickerBtn = new Button(OpenColorPicker) { text = "Open Color Picker" };
|
|
openPickerBtn.style.height = 32;
|
|
openPickerBtn.style.marginBottom = 10;
|
|
container.Add(openPickerBtn);
|
|
|
|
// Async 버튼
|
|
var openPickerAsyncBtn = new Button(() => OpenColorPickerAsync().Forget()) { text = "Open Color Picker (Async)" };
|
|
openPickerAsyncBtn.style.height = 32;
|
|
openPickerAsyncBtn.style.marginBottom = 10;
|
|
container.Add(openPickerAsyncBtn);
|
|
|
|
// 프리셋 색상 버튼들
|
|
var presetLabel = new Label("Preset Colors:");
|
|
presetLabel.style.color = Color.white;
|
|
presetLabel.style.marginTop = 10;
|
|
presetLabel.style.marginBottom = 5;
|
|
container.Add(presetLabel);
|
|
|
|
var presetRow = new VisualElement();
|
|
presetRow.style.flexDirection = FlexDirection.Row;
|
|
presetRow.style.flexWrap = Wrap.Wrap;
|
|
|
|
Color[] presets = { Color.red, Color.green, Color.blue, Color.yellow, Color.cyan, Color.magenta, Color.white, Color.black };
|
|
foreach (var color in presets)
|
|
{
|
|
var presetBtn = new Button(() => SetColor(color));
|
|
presetBtn.style.width = 28;
|
|
presetBtn.style.height = 28;
|
|
presetBtn.style.marginRight = 5;
|
|
presetBtn.style.marginBottom = 5;
|
|
presetBtn.style.backgroundColor = color;
|
|
presetBtn.style.borderTopLeftRadius = 4;
|
|
presetBtn.style.borderTopRightRadius = 4;
|
|
presetBtn.style.borderBottomLeftRadius = 4;
|
|
presetBtn.style.borderBottomRightRadius = 4;
|
|
presetBtn.text = "";
|
|
presetRow.Add(presetBtn);
|
|
}
|
|
|
|
container.Add(presetRow);
|
|
|
|
_root.Add(container);
|
|
}
|
|
|
|
private void OpenColorPicker()
|
|
{
|
|
if (_root == null || _currentPicker != null) return;
|
|
|
|
bool useAlpha = _useAlphaToggle?.value ?? false;
|
|
|
|
_currentPicker = UTKColorPicker.Show(_root, _currentColor, "Select Color", useAlpha);
|
|
|
|
_currentPicker.OnColorChanged += OnColorChanged;
|
|
_currentPicker.OnColorSelected += OnColorSelected;
|
|
}
|
|
|
|
private async UniTaskVoid OpenColorPickerAsync()
|
|
{
|
|
if (_root == null) return;
|
|
|
|
bool useAlpha = _useAlphaToggle?.value ?? true;
|
|
|
|
// ShowAsync를 사용하여 색상 선택 대기
|
|
// OK 클릭 시 선택된 색상 반환, 취소/닫기 시 _currentColor 반환
|
|
Color selectedColor = await UTKColorPicker.ShowAsync(_root, _currentColor, "Select Color (Async)", useAlpha);
|
|
|
|
// 결과 처리
|
|
_currentColor = selectedColor;
|
|
if (_colorPreview != null)
|
|
{
|
|
_colorPreview.style.backgroundColor = selectedColor;
|
|
}
|
|
if (_colorLabel != null)
|
|
{
|
|
_colorLabel.text = ColorToHex(selectedColor);
|
|
}
|
|
|
|
Debug.Log($"[Async] Color Result: {ColorToHex(selectedColor)}");
|
|
}
|
|
|
|
private void OnColorChanged(Color color)
|
|
{
|
|
// 실시간 미리보기 업데이트
|
|
if (_colorPreview != null)
|
|
{
|
|
_colorPreview.style.backgroundColor = color;
|
|
}
|
|
|
|
if (_colorLabel != null)
|
|
{
|
|
_colorLabel.text = ColorToHex(color);
|
|
}
|
|
}
|
|
|
|
private void OnColorSelected(Color color)
|
|
{
|
|
_currentColor = color;
|
|
Debug.Log($"Color Selected: {ColorToHex(color)}");
|
|
|
|
// 피커 참조 정리
|
|
if (_currentPicker != null)
|
|
{
|
|
_currentPicker.OnColorChanged -= OnColorChanged;
|
|
_currentPicker.OnColorSelected -= OnColorSelected;
|
|
_currentPicker = null;
|
|
}
|
|
}
|
|
|
|
private void SetColor(Color color)
|
|
{
|
|
_currentColor = color;
|
|
|
|
if (_colorPreview != null)
|
|
{
|
|
_colorPreview.style.backgroundColor = color;
|
|
}
|
|
|
|
if (_colorLabel != null)
|
|
{
|
|
_colorLabel.text = ColorToHex(color);
|
|
}
|
|
|
|
Debug.Log($"Preset Color Set: {ColorToHex(color)}");
|
|
}
|
|
|
|
private string ColorToHex(Color color)
|
|
{
|
|
bool useAlpha = _useAlphaToggle?.value ?? false;
|
|
if (useAlpha)
|
|
{
|
|
return "#" + ColorUtility.ToHtmlStringRGBA(color);
|
|
}
|
|
return "#" + ColorUtility.ToHtmlStringRGB(color);
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (_currentPicker != null)
|
|
{
|
|
_currentPicker.OnColorChanged -= OnColorChanged;
|
|
_currentPicker.OnColorSelected -= OnColorSelected;
|
|
_currentPicker.Dispose();
|
|
_currentPicker = null;
|
|
}
|
|
}
|
|
}
|
|
}
|