Files
XRLib/Assets/Sample/UIToolkit/UTKStyleGuideSample.Modal.cs

638 lines
20 KiB
C#
Raw Normal View History

2026-01-23 19:04:12 +09:00
#nullable enable
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UIToolkit;
/// <summary>
/// UTKStyleGuideSample의 Modal, Tab, Picker 카테고리 Initialize 메서드들
/// </summary>
public partial class UTKStyleGuideSample
{
#region Tab Initializer
private void InitializeTabViewSample(VisualElement root)
{
var tabContainer = root.Q<VisualElement>("tabview-container");
if (tabContainer != null)
{
var tabView = new UTKTabView();
tabView.style.width = 400;
tabView.style.height = 200;
tabView.AddUTKTab("Tab 1", new Label("Content for Tab 1"));
tabView.AddUTKTab("Tab 2", new Label("Content for Tab 2"));
tabView.AddUTKTab("Tab 3", new Label("Content for Tab 3"));
tabContainer.Add(tabView);
}
SetCodeSamples(root,
csharpCode: @"// 기본 사용법
var tabView = new UTKTabView();
tabView.style.width = 400;
tabView.style.height = 200;
// 탭 추가
tabView.AddUTKTab(""Tab 1"", new Label(""Content for Tab 1""));
tabView.AddUTKTab(""Tab 2"", new Label(""Content for Tab 2""));
tabView.AddUTKTab(""Tab 3"", new Label(""Content for Tab 3""));
// 복잡한 콘텐츠 추가
var contentContainer = new VisualElement();
contentContainer.Add(new Label("" ""));
contentContainer.Add(new UTKButton(""""));
tabView.AddUTKTab(""Tab 4"", contentContainer);
// 탭 선택 이벤트
tabView.OnTabChanged += (index) =>
{
Debug.Log($"" : {index}"");
};
// 프로그램으로 탭 선택
tabView.SelectTab(1); // 두 번째 탭 선택
// 현재 선택된 탭 인덱스
var currentTab = tabView.SelectedTabIndex;",
uxmlCode: @"<!-- UTKTabView는 동적 생성 권장 -->
<!-- C# AddUTKTab으로 -->
<!-- TabView -->
<utk:UTKTabView name=""tab-view-1"" style=""width: 400px; height: 200px;"" />");
}
#endregion
#region Modal Initializers
private void InitializeAlertSample(VisualElement root)
{
if (_root == null) return;
UTKAlert.SetRoot(_root);
var btnInfo = root.Q<UTKButton>("btn-info");
btnInfo?.RegisterCallback<ClickEvent>(_ => ShowInfoAlertAsync().Forget());
var btnSuccess = root.Q<UTKButton>("btn-success");
btnSuccess?.RegisterCallback<ClickEvent>(_ => ShowSuccessAlertAsync().Forget());
var btnWarning = root.Q<UTKButton>("btn-warning");
btnWarning?.RegisterCallback<ClickEvent>(_ => ShowWarningAlertAsync().Forget());
var btnError = root.Q<UTKButton>("btn-error");
btnError?.RegisterCallback<ClickEvent>(_ => ShowErrorAlertAsync().Forget());
var btnConfirm = root.Q<UTKButton>("btn-confirm");
btnConfirm?.RegisterCallback<ClickEvent>(_ => ShowConfirmAlertAsync().Forget());
var btnConfirmCustom = root.Q<UTKButton>("btn-confirm-custom");
btnConfirmCustom?.RegisterCallback<ClickEvent>(_ => ShowConfirmCustomLabelsAsync().Forget());
var btnCallback = root.Q<UTKButton>("btn-callback");
btnCallback?.RegisterCallback<ClickEvent>(_ =>
{
UTKAlert.ShowInfo(_root, "Callback Style", "This uses callback instead of async.",
onClose: () => Debug.Log("Alert closed via callback"));
});
var btnConfirmCallback = root.Q<UTKButton>("btn-confirm-callback");
btnConfirmCallback?.RegisterCallback<ClickEvent>(_ =>
{
UTKAlert.ShowConfirm(_root, "Confirm", "Do you want to proceed?",
onConfirm: () => Debug.Log("Confirmed via callback!"),
onCancel: () => Debug.Log("Cancelled via callback!"));
});
SetCodeSamples(root,
csharpCode: @"// Root 설정 (한 번만)
UTKAlert.SetRoot(rootVisualElement);
// ========================================
// 1. Async/Await 방식 (권장)
// ========================================
// Info Alert
await UTKAlert.ShowInfoAsync("""", "" ."");
// Success Alert
await UTKAlert.ShowSuccessAsync("""", "" !"");
// Warning Alert
await UTKAlert.ShowWarningAsync("""", "" ."");
// Error Alert
await UTKAlert.ShowErrorAsync("""", "" !"");
// Confirm Dialog
bool result = await UTKAlert.ShowConfirmAsync("""", "" ?"");
if (result)
{
Debug.Log("" ."");
}
else
{
Debug.Log("" ."");
}
// Confirm with Custom Labels
bool deleteResult = await UTKAlert.ShowConfirmAsync(
"" "",
"" ?"",
confirmLabel: """",
cancelLabel: """"
);
// closeOnBlockerClick 옵션 (배경 클릭 시 닫기)
await UTKAlert.ShowInfoAsync("""", "" ."", closeOnBlockerClick: true);
// ========================================
// 2. Callback 방식
// ========================================
// Info with Callback
UTKAlert.ShowInfo(rootVisualElement, """", "" ."",
onClose: () => Debug.Log(""Alert가 .""));
// Confirm with Callback
UTKAlert.ShowConfirm(rootVisualElement, """", ""?"",
onConfirm: () => Debug.Log("" !""),
onCancel: () => Debug.Log("" !""));");
}
private async UniTaskVoid ShowInfoAlertAsync()
{
await UTKAlert.ShowInfoAsync("Information", "This is an info message.");
Debug.Log("Info alert closed");
}
private async UniTaskVoid ShowSuccessAlertAsync()
{
await UTKAlert.ShowSuccessAsync("Success", "Operation completed successfully!", closeOnBlockerClick: true);
Debug.Log("Success alert closed");
}
private async UniTaskVoid ShowWarningAlertAsync()
{
await UTKAlert.ShowWarningAsync("Warning", "This is a warning message.");
Debug.Log("Warning alert closed");
}
private async UniTaskVoid ShowErrorAlertAsync()
{
await UTKAlert.ShowErrorAsync("Error", "An error has occurred!");
Debug.Log("Error alert closed");
}
private async UniTaskVoid ShowConfirmAlertAsync()
{
bool result = await UTKAlert.ShowConfirmAsync("Confirm", "Are you sure?");
Debug.Log(result ? "Confirmed!" : "Cancelled!");
}
private async UniTaskVoid ShowConfirmCustomLabelsAsync()
{
bool result = await UTKAlert.ShowConfirmAsync("Delete Item", "Are you sure you want to delete this item?",
confirmLabel: "Delete", cancelLabel: "Keep");
Debug.Log(result ? "Item deleted!" : "Item kept!");
}
private void InitializeToastSample(VisualElement root)
{
var btnInfo = root.Q<UTKButton>("btn-toast-info");
btnInfo?.RegisterCallback<ClickEvent>(_ => UTKToast.Show("This is an info toast!"));
var btnSuccess = root.Q<UTKButton>("btn-toast-success");
btnSuccess?.RegisterCallback<ClickEvent>(_ => UTKToast.ShowSuccess("Operation successful!"));
var btnWarning = root.Q<UTKButton>("btn-toast-warning");
btnWarning?.RegisterCallback<ClickEvent>(_ => UTKToast.ShowWarning("Warning: Check your input!"));
var btnError = root.Q<UTKButton>("btn-toast-error");
btnError?.RegisterCallback<ClickEvent>(_ => UTKToast.ShowError("An error occurred!"));
SetCodeSamples(root,
csharpCode: @"// Root 설정 (한 번만)
UTKToast.SetRoot(rootVisualElement);
// Info Toast (기본)
UTKToast.Show("" !"");
// Success Toast
UTKToast.ShowSuccess("" !"");
// Warning Toast
UTKToast.ShowWarning("": !"");
// Error Toast
UTKToast.ShowError("" !"");
// 지속 시간 설정 (밀리초)
UTKToast.Show(""5 "", 5000);
// 사용 예시
public async UniTask SaveDataAsync()
{
try
{
await SaveToServerAsync();
UTKToast.ShowSuccess("" ."");
}
catch (Exception ex)
{
UTKToast.ShowError($"" : {ex.Message}"");
}
}");
}
private void InitializeTooltipSample(VisualElement root)
{
var btnShort = root.Q<UTKButton>("btn-short-tooltip");
if (btnShort != null)
{
UTKTooltipManager.Instance.AttachTooltip(btnShort, "This is a short tooltip.");
}
var btnLong = root.Q<UTKButton>("btn-long-tooltip");
if (btnLong != null)
{
UTKTooltipManager.Instance.AttachTooltip(btnLong, "This is a longer tooltip message that demonstrates how the tooltip handles multiple lines of text content.");
}
}
#endregion
#region Picker Initializers
private void InitializeColorPickerSample(VisualElement root)
{
if (_root == null) return;
_colorPreviewBox = root.Q<VisualElement>("color-preview-box");
_colorHexLabel = root.Q<Label>("color-hex-label");
if (_colorPreviewBox != null)
{
_colorPreviewBox.style.backgroundColor = _selectedColor;
}
var btnAlpha = root.Q<UTKButton>("btn-color-alpha");
btnAlpha?.RegisterCallback<ClickEvent>(_ => OpenColorPicker(true));
var btnNoAlpha = root.Q<UTKButton>("btn-color-no-alpha");
btnNoAlpha?.RegisterCallback<ClickEvent>(_ => OpenColorPicker(false));
var btnAsync = root.Q<UTKButton>("btn-color-async");
btnAsync?.RegisterCallback<ClickEvent>(_ => OpenColorPickerAsync().Forget());
SetCodeSamples(root,
csharpCode: @"// ========================================
// 1. Callback 방식
// ========================================
// Alpha 포함 (기본)
var picker = UTKColorPicker.Show(rootVisualElement, Color.white, "" "", useAlpha: true);
// 색상 변경 이벤트 (실시간)
picker.OnColorChanged += (color) =>
{
Debug.Log($"" : {ColorUtility.ToHtmlStringRGBA(color)}"");
// 미리보기 업데이트 등
};
// 최종 선택 이벤트
picker.OnColorSelected += (color) =>
{
Debug.Log($"" : {ColorUtility.ToHtmlStringRGBA(color)}"");
// 최종 색상 적용
};
// 취소 이벤트
picker.OnCancelled += () =>
{
Debug.Log("" ."");
};
// Alpha 없이 (RGB만)
var pickerNoAlpha = UTKColorPicker.Show(
rootVisualElement,
Color.red,
"" (Alpha )"",
useAlpha: false
);
// ========================================
// 2. Async/Await 방식 (권장)
// ========================================
// Alpha 포함
Color result = await UTKColorPicker.ShowAsync(
rootVisualElement,
Color.white,
"" (Async)"",
useAlpha: true
);
Debug.Log($"" : #{ColorUtility.ToHtmlStringRGBA(result)}"");
// Alpha 없이
Color rgbColor = await UTKColorPicker.ShowAsync(
rootVisualElement,
Color.red,
""RGB "",
useAlpha: false
);
Debug.Log($"" RGB: #{ColorUtility.ToHtmlStringRGB(rgbColor)}"");
// 사용 예시
public async UniTask ChangeBackgroundColorAsync()
{
Color newColor = await UTKColorPicker.ShowAsync(
_root,
_currentBackgroundColor,
"" "",
useAlpha: true
);
_currentBackgroundColor = newColor;
ApplyBackgroundColor(newColor);
}");
}
private void OpenColorPicker(bool useAlpha)
{
if (_root == null) return;
var picker = UTKColorPicker.Show(_root, _selectedColor, "Select Color", useAlpha);
picker.OnColorChanged += (color) =>
{
if (_colorPreviewBox != null)
_colorPreviewBox.style.backgroundColor = color;
if (_colorHexLabel != null)
_colorHexLabel.text = useAlpha
? $"#{ColorUtility.ToHtmlStringRGBA(color)}"
: $"#{ColorUtility.ToHtmlStringRGB(color)}";
};
picker.OnColorSelected += (color) =>
{
_selectedColor = color;
Debug.Log($"Color Selected: #{(useAlpha ? ColorUtility.ToHtmlStringRGBA(color) : ColorUtility.ToHtmlStringRGB(color))}");
};
}
private async UniTaskVoid OpenColorPickerAsync()
{
if (_root == null) return;
Color result = await UTKColorPicker.ShowAsync(_root, _selectedColor, "Select Color (Async)", useAlpha: true);
_selectedColor = result;
if (_colorPreviewBox != null)
_colorPreviewBox.style.backgroundColor = result;
if (_colorHexLabel != null)
_colorHexLabel.text = $"#{ColorUtility.ToHtmlStringRGBA(result)}";
Debug.Log($"[Async] Color Result: #{ColorUtility.ToHtmlStringRGBA(result)}");
}
private void InitializeDatePickerSample(VisualElement root)
{
if (_root == null) return;
UTKDatePicker.SetDayNames(new[] { "일", "월", "화", "수", "목", "금", "토" });
_dateLabel = root.Q<Label>("date-label");
_rangeDateLabel = root.Q<Label>("range-date-label");
if (_dateLabel != null)
_dateLabel.text = $"Selected: {_selectedDate:yyyy-MM-dd}";
if (_rangeDateLabel != null)
_rangeDateLabel.text = $"Range: {_rangeStartDate:yyyy-MM-dd} ~ {_rangeEndDate:yyyy-MM-dd}";
var btnDateOnly = root.Q<UTKButton>("btn-date-only");
btnDateOnly?.RegisterCallback<ClickEvent>(_ => OpenDatePicker(UTKDatePicker.PickerMode.DateOnly));
var btnDateTime = root.Q<UTKButton>("btn-date-time");
btnDateTime?.RegisterCallback<ClickEvent>(_ => OpenDatePicker(UTKDatePicker.PickerMode.DateAndTime));
var btnDateAsync = root.Q<UTKButton>("btn-date-async");
btnDateAsync?.RegisterCallback<ClickEvent>(_ => OpenDatePickerAsync().Forget());
var btnRange = root.Q<UTKButton>("btn-range");
btnRange?.RegisterCallback<ClickEvent>(_ => OpenDateRangePicker());
var btnRangeAsync = root.Q<UTKButton>("btn-range-async");
btnRangeAsync?.RegisterCallback<ClickEvent>(_ => OpenDateRangePickerAsync().Forget());
SetCodeSamples(root,
csharpCode: @"// 요일 이름 설정 (선택사항, 한 번만)
UTKDatePicker.SetDayNames(new[] { """", """", """", """", """", """", """" });
// ========================================
// 1. 단일 날짜 선택 - Callback 방식
// ========================================
// Date Only
var datePicker = UTKDatePicker.Show(
rootVisualElement,
DateTime.Today,
UTKDatePicker.PickerMode.DateOnly,
"" ""
);
datePicker.OnDateSelected += (date) =>
{
Debug.Log($"" : {date:yyyy-MM-dd}"");
};
datePicker.OnCancelled += () =>
{
Debug.Log("" ."");
};
// Date & Time
var dateTimePicker = UTKDatePicker.Show(
rootVisualElement,
DateTime.Now,
UTKDatePicker.PickerMode.DateAndTime,
"" ""
);
dateTimePicker.OnDateSelected += (date) =>
{
Debug.Log($"" /: {date:yyyy-MM-dd HH:mm}"");
};
// ========================================
// 2. 단일 날짜 선택 - Async/Await 방식 (권장)
// ========================================
// Date Only
DateTime? dateResult = await UTKDatePicker.ShowAsync(
rootVisualElement,
DateTime.Today,
UTKDatePicker.PickerMode.DateOnly,
"" (Async)""
);
if (dateResult.HasValue)
{
Debug.Log($"" : {dateResult.Value:yyyy-MM-dd}"");
}
else
{
Debug.Log("" ."");
}
// Date & Time
DateTime? dateTimeResult = await UTKDatePicker.ShowAsync(
rootVisualElement,
DateTime.Now,
UTKDatePicker.PickerMode.DateAndTime,
"" ""
);
if (dateTimeResult.HasValue)
{
Debug.Log($"" /: {dateTimeResult.Value:yyyy-MM-dd HH:mm}"");
}
// ========================================
// 3. 날짜 범위 선택 - Callback 방식
// ========================================
var rangePicker = UTKDatePicker.ShowRange(
rootVisualElement,
DateTime.Today,
DateTime.Today.AddDays(7),
includeTime: false,
"" ""
);
rangePicker.OnDateRangeSelected += (start, end) =>
{
Debug.Log($"" : {start:yyyy-MM-dd} ~ {end:yyyy-MM-dd}"");
};
rangePicker.OnCancelled += () =>
{
Debug.Log("" ."");
};
// ========================================
// 4. 날짜 범위 선택 - Async/Await 방식 (권장)
// ========================================
var rangeResult = await UTKDatePicker.ShowRangeAsync(
rootVisualElement,
DateTime.Today,
DateTime.Today.AddDays(7),
includeTime: false,
"" (Async)""
);
if (rangeResult.HasValue)
{
Debug.Log($"" : {rangeResult.Value.Start:yyyy-MM-dd} ~ {rangeResult.Value.End:yyyy-MM-dd}"");
}
else
{
Debug.Log("" ."");
}
// 시간 포함 범위 선택
var rangeTimeResult = await UTKDatePicker.ShowRangeAsync(
rootVisualElement,
DateTime.Now,
DateTime.Now.AddDays(7),
includeTime: true,
"" ""
);
if (rangeTimeResult.HasValue)
{
Debug.Log($"": {rangeTimeResult.Value.Start:yyyy-MM-dd HH:mm}"");
Debug.Log($"": {rangeTimeResult.Value.End:yyyy-MM-dd HH:mm}"");
}");
}
private void OpenDatePicker(UTKDatePicker.PickerMode mode)
{
if (_root == null) return;
string title = mode == UTKDatePicker.PickerMode.DateOnly ? "Select Date" : "Select Date & Time";
var picker = UTKDatePicker.Show(_root, _selectedDate, mode, title);
picker.OnDateSelected += (date) =>
{
_selectedDate = date;
if (_dateLabel != null)
{
_dateLabel.text = mode == UTKDatePicker.PickerMode.DateOnly
? $"Selected: {date:yyyy-MM-dd}"
: $"Selected: {date:yyyy-MM-dd HH:mm}";
}
Debug.Log($"Date Selected: {date:yyyy-MM-dd HH:mm}");
};
}
private async UniTaskVoid OpenDatePickerAsync()
{
if (_root == null) return;
DateTime? result = await UTKDatePicker.ShowAsync(_root, _selectedDate, UTKDatePicker.PickerMode.DateOnly, "Select Date (Async)");
if (result.HasValue)
{
_selectedDate = result.Value;
if (_dateLabel != null)
_dateLabel.text = $"Selected: {result.Value:yyyy-MM-dd}";
Debug.Log($"[Async] Date Result: {result.Value:yyyy-MM-dd}");
}
else
{
Debug.Log("[Async] Date selection cancelled");
}
}
private void OpenDateRangePicker()
{
if (_root == null) return;
var picker = UTKDatePicker.ShowRange(_root, _rangeStartDate, _rangeEndDate, false, "Select Date Range");
picker.OnDateRangeSelected += (start, end) =>
{
_rangeStartDate = start;
_rangeEndDate = end;
if (_rangeDateLabel != null)
_rangeDateLabel.text = $"Range: {start:yyyy-MM-dd} ~ {end:yyyy-MM-dd}";
Debug.Log($"Date Range Selected: {start:yyyy-MM-dd} ~ {end:yyyy-MM-dd}");
};
}
private async UniTaskVoid OpenDateRangePickerAsync()
{
if (_root == null) return;
var result = await UTKDatePicker.ShowRangeAsync(_root, _rangeStartDate, _rangeEndDate, false, "Select Date Range (Async)");
if (result.HasValue)
{
_rangeStartDate = result.Value.Start;
_rangeEndDate = result.Value.End;
if (_rangeDateLabel != null)
_rangeDateLabel.text = $"Range: {result.Value.Start:yyyy-MM-dd} ~ {result.Value.End:yyyy-MM-dd}";
Debug.Log($"[Async] Range Result: {result.Value.Start:yyyy-MM-dd} ~ {result.Value.End:yyyy-MM-dd}");
}
else
{
Debug.Log("[Async] Date range selection cancelled");
}
}
#endregion
}