396 lines
14 KiB
C#
396 lines
14 KiB
C#
#nullable enable
|
|
using System;
|
|
using Cysharp.Threading.Tasks;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
using UVC.UIToolkit;
|
|
|
|
namespace UVC.Sample.UIToolkit
|
|
{
|
|
/// <summary>
|
|
/// UTKColorPicker 샘플 코드
|
|
/// 버튼 클릭으로 컬러 피커를 열고 선택된 색상을 미리보기에 표시
|
|
/// </summary>
|
|
public class UTKColorPickerSample : MonoBehaviour
|
|
{
|
|
[SerializeField] private UIDocument? _uiDocument;
|
|
|
|
[SerializeField]
|
|
[Tooltip("시작 시 적용할 테마")]
|
|
private UTKTheme initialTheme = UTKTheme.Dark;
|
|
|
|
private UTKToggle _themeToggle;
|
|
|
|
private VisualElement? _root;
|
|
private VisualElement? _colorPreview;
|
|
private Label? _colorLabel;
|
|
private Toggle? _useAlphaToggle;
|
|
|
|
private Color _currentColor = Color.blue;
|
|
private UTKColorPicker? _currentPicker;
|
|
|
|
private void Start()
|
|
{
|
|
// UIDocument 참조 확인
|
|
var doc = GetComponent<UIDocument>();
|
|
if (doc == null)
|
|
{
|
|
Debug.LogError("UIDocument가 할당되지 않았습니다.");
|
|
return;
|
|
}
|
|
_uiDocument = doc;
|
|
|
|
var toggle = _uiDocument.rootVisualElement.Q<UTKToggle>("toggle");
|
|
if (toggle == null)
|
|
{
|
|
Debug.LogError("UXML에서 UTKToggle을 찾을 수 없습니다.");
|
|
return;
|
|
}
|
|
_themeToggle = toggle;
|
|
|
|
UTKThemeManager.Instance.RegisterRoot(_uiDocument.rootVisualElement);
|
|
UTKThemeManager.Instance.SetTheme(initialTheme);
|
|
|
|
_themeToggle.OnValueChanged += (isOn) =>
|
|
{
|
|
UTKThemeManager.Instance.SetTheme(!isOn ? UTKTheme.Dark : UTKTheme.Light);
|
|
};
|
|
|
|
_root = _uiDocument.rootVisualElement;
|
|
UTKColorPicker.SetRoot(_root);
|
|
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);
|
|
|
|
// Alpha 프리셋 버튼들
|
|
var alphaPresetLabel = new Label("Alpha Presets:");
|
|
alphaPresetLabel.style.color = Color.white;
|
|
alphaPresetLabel.style.marginTop = 10;
|
|
alphaPresetLabel.style.marginBottom = 5;
|
|
container.Add(alphaPresetLabel);
|
|
|
|
var alphaPresetRow = new VisualElement();
|
|
alphaPresetRow.style.flexDirection = FlexDirection.Row;
|
|
alphaPresetRow.style.marginBottom = 10;
|
|
|
|
// Alpha 값이 다른 프리셋 버튼들
|
|
float[] alphaValues = { 1.0f, 0.75f, 0.5f, 0.25f };
|
|
foreach (var alpha in alphaValues)
|
|
{
|
|
var alphaBtn = new Button(() => SetColorWithAlpha(alpha));
|
|
alphaBtn.style.width = 50;
|
|
alphaBtn.style.height = 28;
|
|
alphaBtn.style.marginRight = 5;
|
|
alphaBtn.style.backgroundColor = new Color(0.3f, 0.3f, 0.3f);
|
|
alphaBtn.style.borderTopLeftRadius = 4;
|
|
alphaBtn.style.borderTopRightRadius = 4;
|
|
alphaBtn.style.borderBottomLeftRadius = 4;
|
|
alphaBtn.style.borderBottomRightRadius = 4;
|
|
alphaBtn.text = $"{(int)(alpha * 100)}%";
|
|
alphaBtn.style.fontSize = 11;
|
|
alphaPresetRow.Add(alphaBtn);
|
|
}
|
|
|
|
container.Add(alphaPresetRow);
|
|
|
|
// Alpha 활성화/비활성화 직접 호출 버튼들
|
|
var alphaControlLabel = new Label("Alpha Control Examples:");
|
|
alphaControlLabel.style.color = Color.white;
|
|
alphaControlLabel.style.marginTop = 5;
|
|
alphaControlLabel.style.marginBottom = 5;
|
|
container.Add(alphaControlLabel);
|
|
|
|
var alphaControlRow = new VisualElement();
|
|
alphaControlRow.style.flexDirection = FlexDirection.Row;
|
|
alphaControlRow.style.marginBottom = 10;
|
|
|
|
var withAlphaBtn = new Button(OpenColorPickerWithAlpha) { text = "With Alpha" };
|
|
withAlphaBtn.style.height = 28;
|
|
withAlphaBtn.style.flexGrow = 1;
|
|
withAlphaBtn.style.marginRight = 5;
|
|
alphaControlRow.Add(withAlphaBtn);
|
|
|
|
var withoutAlphaBtn = new Button(OpenColorPickerWithoutAlpha) { text = "Without Alpha" };
|
|
withoutAlphaBtn.style.height = 28;
|
|
withoutAlphaBtn.style.flexGrow = 1;
|
|
alphaControlRow.Add(withoutAlphaBtn);
|
|
|
|
container.Add(alphaControlRow);
|
|
|
|
// 프리셋 색상 버튼들
|
|
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(_currentColor, "Select Color", useAlpha);
|
|
|
|
_currentPicker.OnColorChanged += OnColorChanged;
|
|
_currentPicker.OnColorSelected += OnColorSelected;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Alpha 채널 활성화 상태로 컬러 피커 열기
|
|
/// </summary>
|
|
private void OpenColorPickerWithAlpha()
|
|
{
|
|
if (_root == null || _currentPicker != null) return;
|
|
|
|
// useAlpha = true로 명시적 호출
|
|
_currentPicker = UTKColorPicker.Show(_currentColor, "Select Color (Alpha ON)", useAlpha: true);
|
|
|
|
_currentPicker.OnColorChanged += OnColorChanged;
|
|
_currentPicker.OnColorSelected += OnColorSelected;
|
|
|
|
Debug.Log("[Sample] ColorPicker opened with Alpha channel enabled");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Alpha 채널 비활성화 상태로 컬러 피커 열기
|
|
/// </summary>
|
|
private void OpenColorPickerWithoutAlpha()
|
|
{
|
|
if (_root == null || _currentPicker != null) return;
|
|
|
|
// useAlpha = false로 명시적 호출
|
|
_currentPicker = UTKColorPicker.Show(_currentColor, "Select Color (Alpha OFF)", useAlpha: false);
|
|
|
|
_currentPicker.OnColorChanged += OnColorChanged;
|
|
_currentPicker.OnColorSelected += OnColorSelected;
|
|
|
|
Debug.Log("[Sample] ColorPicker opened without Alpha channel");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 현재 색상의 Alpha 값을 변경
|
|
/// </summary>
|
|
private void SetColorWithAlpha(float alpha)
|
|
{
|
|
_currentColor = new Color(_currentColor.r, _currentColor.g, _currentColor.b, alpha);
|
|
|
|
if (_colorPreview != null)
|
|
{
|
|
_colorPreview.style.backgroundColor = _currentColor;
|
|
}
|
|
|
|
if (_colorLabel != null)
|
|
{
|
|
_colorLabel.text = ColorToHex(_currentColor);
|
|
}
|
|
|
|
Debug.Log($"[Sample] Alpha set to {(int)(alpha * 100)}% - Color: {ColorToHex(_currentColor)}");
|
|
}
|
|
|
|
private async UniTaskVoid OpenColorPickerAsync()
|
|
{
|
|
if (_root == null) return;
|
|
|
|
bool useAlpha = _useAlphaToggle?.value ?? true;
|
|
|
|
// ShowAsync를 사용하여 색상 선택 대기
|
|
// OK 클릭 시 선택된 색상 반환, 취소/닫기 시 _currentColor 반환
|
|
Color selectedColor = await UTKColorPicker.ShowAsync(_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;
|
|
}
|
|
}
|
|
}
|
|
}
|