UTKNotification 수정 중

This commit is contained in:
logonkhi
2026-02-23 19:38:27 +09:00
parent 106e7f51be
commit b9b394935e
31 changed files with 961 additions and 422 deletions

View File

@@ -57,6 +57,7 @@ namespace UVC.Sample.UIToolkit
};
_root = _uiDocument.rootVisualElement;
UTKColorPicker.SetRoot(_root);
CreateSampleUI();
}
@@ -243,7 +244,7 @@ namespace UVC.Sample.UIToolkit
bool useAlpha = _useAlphaToggle?.value ?? false;
_currentPicker = UTKColorPicker.Show(_root, _currentColor, "Select Color", useAlpha);
_currentPicker = UTKColorPicker.Show(_currentColor, "Select Color", useAlpha);
_currentPicker.OnColorChanged += OnColorChanged;
_currentPicker.OnColorSelected += OnColorSelected;
@@ -257,7 +258,7 @@ namespace UVC.Sample.UIToolkit
if (_root == null || _currentPicker != null) return;
// useAlpha = true로 명시적 호출
_currentPicker = UTKColorPicker.Show(_root, _currentColor, "Select Color (Alpha ON)", useAlpha: true);
_currentPicker = UTKColorPicker.Show(_currentColor, "Select Color (Alpha ON)", useAlpha: true);
_currentPicker.OnColorChanged += OnColorChanged;
_currentPicker.OnColorSelected += OnColorSelected;
@@ -273,7 +274,7 @@ namespace UVC.Sample.UIToolkit
if (_root == null || _currentPicker != null) return;
// useAlpha = false로 명시적 호출
_currentPicker = UTKColorPicker.Show(_root, _currentColor, "Select Color (Alpha OFF)", useAlpha: false);
_currentPicker = UTKColorPicker.Show(_currentColor, "Select Color (Alpha OFF)", useAlpha: false);
_currentPicker.OnColorChanged += OnColorChanged;
_currentPicker.OnColorSelected += OnColorSelected;
@@ -309,7 +310,7 @@ namespace UVC.Sample.UIToolkit
// ShowAsync를 사용하여 색상 선택 대기
// OK 클릭 시 선택된 색상 반환, 취소/닫기 시 _currentColor 반환
Color selectedColor = await UTKColorPicker.ShowAsync(_root, _currentColor, "Select Color (Async)", useAlpha);
Color selectedColor = await UTKColorPicker.ShowAsync(_currentColor, "Select Color (Async)", useAlpha);
// 결과 처리
_currentColor = selectedColor;

View File

@@ -64,6 +64,7 @@ namespace UVC.Sample.UIToolkit
Debug.Log($"LocalizationManager: LoadDefaultLocalizationData success: {success}");
_root = _uiDocument.rootVisualElement;
UTKDatePicker.SetRoot(_root);
CreateSampleUI();
}
@@ -227,7 +228,6 @@ namespace UVC.Sample.UIToolkit
if (_root == null || _currentPicker != null) return;
_currentPicker = UTKDatePicker.Show(
_root,
_selectedDate,
UTKDatePicker.PickerMode.DateOnly,
"Select Date"
@@ -242,7 +242,6 @@ namespace UVC.Sample.UIToolkit
if (_root == null || _currentPicker != null) return;
_currentPicker = UTKDatePicker.Show(
_root,
_selectedDateTime,
UTKDatePicker.PickerMode.DateAndTime,
"Select Date & Time"
@@ -259,7 +258,6 @@ namespace UVC.Sample.UIToolkit
// ShowAsync를 사용하여 날짜 선택 대기
// OK 클릭 시 선택된 날짜 반환, 취소/닫기 시 null 반환
DateTime? result = await UTKDatePicker.ShowAsync(
_root,
_selectedDate,
UTKDatePicker.PickerMode.DateOnly,
"Select Date (Async)"
@@ -350,7 +348,6 @@ namespace UVC.Sample.UIToolkit
if (_root == null || _currentPicker != null) return;
_currentPicker = UTKDatePicker.ShowRange(
_root,
_rangeStartDate,
_rangeEndDate,
false,
@@ -368,7 +365,6 @@ namespace UVC.Sample.UIToolkit
// ShowRangeAsync를 사용하여 날짜 범위 선택 대기
// OK 클릭 시 선택된 범위 반환, 취소/닫기 시 null 반환
var result = await UTKDatePicker.ShowRangeAsync(
_root,
_rangeStartDate,
_rangeEndDate,
false,

View File

@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.Locale;
using UVC.UIToolkit;
namespace UVC.Sample.UIToolkit
@@ -26,6 +27,10 @@ namespace UVC.Sample.UIToolkit
private void Start()
{
bool success = LocalizationManager.Instance.LoadDefaultLocalizationData("KO");
Debug.Log($"LocalizationManager: LoadDefaultLocalizationData success: {success}");
// UIDocument 참조 확인
var doc = GetComponent<UIDocument>();
if (doc == null)

View File

@@ -203,14 +203,14 @@ var currentTab = tabView.SelectedIndex;",
var btnCallback = root.Q<UTKButton>("btn-callback");
btnCallback?.RegisterCallback<ClickEvent>(_ =>
{
UTKAlert.ShowInfo(_root, "Callback Style", "This uses callback instead of async.",
UTKAlert.ShowInfo("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?",
UTKAlert.ShowConfirm("Confirm", "Do you want to proceed?",
onConfirm: () => Debug.Log("Confirmed via callback!"),
onCancel: () => Debug.Log("Cancelled via callback!"));
});
@@ -262,11 +262,11 @@ await UTKAlert.ShowInfoAsync(""정보"", ""배경을 클릭해도 닫힙니다."
// ========================================
// Info with Callback
UTKAlert.ShowInfo(rootVisualElement, ""정보"", ""콜백 방식입니다."",
UTKAlert.ShowInfo(""정보"", ""콜백 방식입니다."",
onClose: () => Debug.Log(""Alert가 닫혔습니다.""));
// Confirm with Callback
UTKAlert.ShowConfirm(rootVisualElement, ""확인"", ""진행하시겠습니까?"",
UTKAlert.ShowConfirm(""확인"", ""진행하시겠습니까?"",
onConfirm: () => Debug.Log(""확인 클릭!""),
onCancel: () => Debug.Log(""취소 클릭!""));");
}
@@ -405,12 +405,383 @@ for (int i = 0; i < buttons.Length; i++)
#endregion
#region Modal Initializers (UTKModal)
private void InitializeModalSample(VisualElement root)
{
if (_root == null) return;
UTKModal.SetRoot(_root);
// Modal Sizes
var btnSmall = root.Q<UTKButton>("btn-modal-small");
btnSmall?.RegisterCallback<ClickEvent>(_ => ShowModalWithSize(UTKModal.ModalSize.Small));
var btnMedium = root.Q<UTKButton>("btn-modal-medium");
btnMedium?.RegisterCallback<ClickEvent>(_ => ShowModalWithSize(UTKModal.ModalSize.Medium));
var btnLarge = root.Q<UTKButton>("btn-modal-large");
btnLarge?.RegisterCallback<ClickEvent>(_ => ShowModalWithSize(UTKModal.ModalSize.Large));
var btnFullScreen = root.Q<UTKButton>("btn-modal-fullscreen");
btnFullScreen?.RegisterCallback<ClickEvent>(_ => ShowModalWithSize(UTKModal.ModalSize.FullScreen));
// Options
var btnFooter = root.Q<UTKButton>("btn-modal-footer");
btnFooter?.RegisterCallback<ClickEvent>(_ =>
{
var modal = UTKModal.Show("푸터 버튼 모달", UTKModal.ModalSize.Medium);
modal.Add(new Label("확인 또는 취소를 선택하세요."));
var confirmBtn = new UTKButton("확인") { Variant = UTKButton.ButtonVariant.Primary };
confirmBtn.RegisterCallback<ClickEvent>(_ =>
{
Debug.Log("Modal confirmed");
modal.Close();
});
var cancelBtn = new UTKButton("취소") { Variant = UTKButton.ButtonVariant.Normal };
cancelBtn.RegisterCallback<ClickEvent>(_ =>
{
Debug.Log("Modal cancelled");
modal.Close();
});
modal.AddToFooter(cancelBtn);
modal.AddToFooter(confirmBtn);
});
var btnNoClose = root.Q<UTKButton>("btn-modal-no-close");
btnNoClose?.RegisterCallback<ClickEvent>(_ =>
{
var modal = UTKModal.Show("닫기 버튼 없음", UTKModal.ModalSize.Small);
modal.ShowCloseButton = false;
modal.Add(new Label("닫기 버튼이 없습니다.\n배경을 클릭하면 닫힙니다."));
});
var btnNoBackdrop = root.Q<UTKButton>("btn-modal-no-backdrop");
btnNoBackdrop?.RegisterCallback<ClickEvent>(_ =>
{
var modal = UTKModal.Show("배경 클릭 비활성화", UTKModal.ModalSize.Small);
modal.CloseOnBackdropClick = false;
modal.Add(new Label("배경을 클릭해도 닫히지 않습니다.\nX 버튼으로만 닫을 수 있습니다."));
});
// Custom Content - Form Modal
var btnForm = root.Q<UTKButton>("btn-modal-form");
btnForm?.RegisterCallback<ClickEvent>(_ =>
{
var modal = UTKModal.Show("사용자 정보 입력", UTKModal.ModalSize.Medium);
var nameField = new UTKInputField("이름");
var emailField = new UTKInputField("이메일");
modal.Add(nameField);
modal.Add(emailField);
var submitBtn = new UTKButton("제출") { Variant = UTKButton.ButtonVariant.Primary };
submitBtn.RegisterCallback<ClickEvent>(_ =>
{
Debug.Log($"Name: {nameField.value}, Email: {emailField.value}");
modal.Close();
});
var cancelBtn = new UTKButton("취소") { Variant = UTKButton.ButtonVariant.Normal };
cancelBtn.RegisterCallback<ClickEvent>(_ => modal.Close());
modal.AddToFooter(cancelBtn);
modal.AddToFooter(submitBtn);
});
SetCodeSamples(root,
csharpCode: @"// Root 설정 (한 번만)
UTKModal.SetRoot(rootVisualElement);
// ========================================
// 1. 기본 모달 표시
// ========================================
var modal = UTKModal.Show(""제목"", UTKModal.ModalSize.Medium);
modal.Add(new Label(""모달 내용""));
// 닫힘 이벤트
modal.OnClosed += () => Debug.Log(""모달 닫힘"");
// ========================================
// 2. 모달 크기
// ========================================
// Small
UTKModal.Show(""Small"", UTKModal.ModalSize.Small);
// Medium (기본)
UTKModal.Show(""Medium"", UTKModal.ModalSize.Medium);
// Large
UTKModal.Show(""Large"", UTKModal.ModalSize.Large);
// FullScreen
UTKModal.Show(""FullScreen"", UTKModal.ModalSize.FullScreen);
// ========================================
// 3. 옵션 설정
// ========================================
var modal = UTKModal.Show(""설정"");
// 닫기 버튼 숨기기
modal.ShowCloseButton = false;
// 배경 클릭 시 닫기 비활성화
modal.CloseOnBackdropClick = false;
// 푸터 숨기기
modal.SetFooterVisible(false);
// ========================================
// 4. 푸터 버튼 추가
// ========================================
var modal = UTKModal.Show(""확인 모달"");
modal.Add(new Label(""정말 삭제하시겠습니까?""));
var confirmBtn = new UTKButton(""삭제"") { Variant = UTKButton.ButtonVariant.Danger };
confirmBtn.RegisterCallback<ClickEvent>(_ =>
{
Debug.Log(""삭제 실행"");
modal.Close();
});
var cancelBtn = new UTKButton(""취소"") { Variant = UTKButton.ButtonVariant.Normal };
cancelBtn.RegisterCallback<ClickEvent>(_ => modal.Close());
modal.AddToFooter(cancelBtn);
modal.AddToFooter(confirmBtn);
// ========================================
// 5. 폼 모달
// ========================================
var modal = UTKModal.Show(""사용자 정보"");
var nameField = new UTKInputField(""이름"");
var emailField = new UTKInputField(""이메일"");
modal.Add(nameField);
modal.Add(emailField);
var submitBtn = new UTKButton(""제출"") { Variant = UTKButton.ButtonVariant.Primary };
submitBtn.RegisterCallback<ClickEvent>(_ =>
{
Debug.Log($""Name: {nameField.value}, Email: {emailField.value}"");
modal.Close();
});
modal.AddToFooter(submitBtn);
// ========================================
// 6. 프로그래밍 방식 닫기
// ========================================
var modal = UTKModal.Show(""타이머 모달"");
modal.Add(new Label(""3초 후 자동으로 닫힙니다.""));
modal.ShowCloseButton = false;
modal.CloseOnBackdropClick = false;
// 3초 후 닫기
modal.schedule.Execute(() => modal.Close()).StartingIn(3000);",
uxmlCode: @"<!-- 네임스페이스 선언 -->
<ui:UXML xmlns:utk=""UVC.UIToolkit"">
<!-- 기본 모달 -->
<utk:UTKModal title=""설정"" size=""Medium"" show-close-button=""true"">
<ui:Label text=""모달 내용을 여기에 추가하세요"" />
</utk:UTKModal>
<!-- Small 모달, 닫기 버튼 없음 -->
<utk:UTKModal title=""알림"" size=""Small"" show-close-button=""false"">
<ui:Label text=""간단한 알림"" />
</utk:UTKModal>
<!-- 배경 클릭 닫기 비활성화 -->
<utk:UTKModal title=""중요"" size=""Medium"" close-on-backdrop-click=""false"">
<ui:Label text=""반드시 확인해야 하는 내용"" />
</utk:UTKModal>
</ui:UXML>");
}
private void ShowModalWithSize(UTKModal.ModalSize size)
{
if (_root == null) return;
var modal = UTKModal.Show($"{size} Modal", size);
modal.Add(new Label($"이것은 {size} 크기의 모달입니다."));
modal.OnClosed += () => Debug.Log($"{size} modal closed");
}
#endregion
#region Notification Initializers
private void InitializeNotificationSample(VisualElement root)
{
if (_root == null) return;
UTKNotification.SetRoot(_root);
// Notification Types
var btnInfo = root.Q<UTKButton>("btn-noti-info");
btnInfo?.RegisterCallback<ClickEvent>(_ =>
UTKNotification.ShowInfo("정보", "이것은 정보 알림입니다."));
var btnSuccess = root.Q<UTKButton>("btn-noti-success");
btnSuccess?.RegisterCallback<ClickEvent>(_ =>
UTKNotification.ShowSuccess("성공", "작업이 성공적으로 완료되었습니다!"));
var btnWarning = root.Q<UTKButton>("btn-noti-warning");
btnWarning?.RegisterCallback<ClickEvent>(_ =>
UTKNotification.ShowWarning("경고", "주의가 필요한 상황입니다."));
var btnError = root.Q<UTKButton>("btn-noti-error");
btnError?.RegisterCallback<ClickEvent>(_ =>
UTKNotification.ShowError("오류", "오류가 발생했습니다!"));
// Position
var btnTopLeft = root.Q<UTKButton>("btn-noti-top-left");
btnTopLeft?.RegisterCallback<ClickEvent>(_ =>
UTKNotification.Show("Top Left", "TopLeft 위치 알림",
UTKNotification.NotificationType.Info, UTKNotification.NotificationPosition.TopLeft));
var btnTopRight = root.Q<UTKButton>("btn-noti-top-right");
btnTopRight?.RegisterCallback<ClickEvent>(_ =>
UTKNotification.Show("Top Right", "TopRight 위치 알림",
UTKNotification.NotificationType.Info, UTKNotification.NotificationPosition.TopRight));
var btnBottomLeft = root.Q<UTKButton>("btn-noti-bottom-left");
btnBottomLeft?.RegisterCallback<ClickEvent>(_ =>
UTKNotification.Show("Bottom Left", "BottomLeft 위치 알림",
UTKNotification.NotificationType.Info, UTKNotification.NotificationPosition.BottomLeft));
var btnBottomRight = root.Q<UTKButton>("btn-noti-bottom-right");
btnBottomRight?.RegisterCallback<ClickEvent>(_ =>
UTKNotification.Show("Bottom Right", "BottomRight 위치 알림",
UTKNotification.NotificationType.Info, UTKNotification.NotificationPosition.BottomRight));
// With Actions
var btnAction = root.Q<UTKButton>("btn-noti-action");
btnAction?.RegisterCallback<ClickEvent>(_ =>
{
var notification = UTKNotification.Show("업데이트 가능",
"새로운 버전이 있습니다. 업데이트하시겠습니까?",
UTKNotification.NotificationType.Info, UTKNotification.NotificationPosition.TopRight);
notification.AddAction("업데이트", "update");
notification.AddAction("나중에", "later");
notification.OnActionClicked += (actionId) =>
{
Debug.Log($"Action clicked: {actionId}");
};
});
var btnPersistent = root.Q<UTKButton>("btn-noti-persistent");
btnPersistent?.RegisterCallback<ClickEvent>(_ =>
{
var notification = UTKNotification.Show("수동 닫기",
"이 알림은 자동으로 닫히지 않습니다. X 버튼을 눌러 닫아주세요.",
UTKNotification.NotificationType.Warning, UTKNotification.NotificationPosition.TopRight,
duration: 0);
notification.OnClosed += () => Debug.Log("Persistent notification closed");
});
SetCodeSamples(root,
csharpCode: @"// Root 설정 (한 번만)
UTKNotification.SetRoot(rootVisualElement);
// ========================================
// 1. 기본 알림 타입
// ========================================
// Info
UTKNotification.ShowInfo(""정보"", ""이것은 정보 알림입니다."");
// Success
UTKNotification.ShowSuccess(""성공"", ""작업이 완료되었습니다!"");
// Warning
UTKNotification.ShowWarning(""경고"", ""주의가 필요합니다."");
// Error
UTKNotification.ShowError(""오류"", ""오류가 발생했습니다!"");
// ========================================
// 2. 위치 지정
// ========================================
UTKNotification.Show(""제목"", ""메시지"",
UTKNotification.NotificationType.Info,
UTKNotification.NotificationPosition.TopRight); // 기본값
UTKNotification.Show(""제목"", ""메시지"",
UTKNotification.NotificationType.Success,
UTKNotification.NotificationPosition.BottomLeft);
// ========================================
// 3. 지속 시간 설정
// ========================================
// 기본 5초
UTKNotification.ShowInfo(""정보"", ""5초 후 자동 닫힘"");
// 10초
UTKNotification.ShowInfo(""정보"", ""10초 후 자동 닫힘"", duration: 10000);
// 수동 닫기 (자동 닫힘 없음)
UTKNotification.ShowWarning(""경고"", ""수동으로 닫아주세요."", duration: 0);
// ========================================
// 4. 액션 버튼 추가
// ========================================
var notification = UTKNotification.Show(
""업데이트 가능"", ""새로운 버전이 있습니다."",
UTKNotification.NotificationType.Info,
UTKNotification.NotificationPosition.TopRight);
notification.AddAction(""업데이트"", ""update"");
notification.AddAction(""나중에"", ""later"");
notification.OnActionClicked += (actionId) =>
{
if (actionId == ""update"")
Debug.Log(""업데이트 시작"");
else
Debug.Log(""나중에 업데이트"");
};
// ========================================
// 5. 닫힘 이벤트
// ========================================
var noti = UTKNotification.ShowInfo(""알림"", ""메시지"");
noti.OnClosed += () => Debug.Log(""알림이 닫혔습니다."");
// ========================================
// 6. 인스턴스 직접 생성
// ========================================
var custom = new UTKNotification(""제목"", ""메시지"", UTKNotification.NotificationType.Success);
custom.Duration = 0;
custom.AddAction(""확인"", ""confirm"");
rootVisualElement.Add(custom);");
}
#endregion
#region Picker Initializers
private void InitializeColorPickerSample(VisualElement root)
{
if (_root == null) return;
UTKColorPicker.SetRoot(_root);
_colorPreviewBox = root.Q<VisualElement>("color-preview-box");
_colorHexLabel = root.Q<Label>("color-hex-label");
@@ -429,12 +800,15 @@ for (int i = 0; i < buttons.Length; i++)
btnAsync?.RegisterCallback<ClickEvent>(_ => OpenColorPickerAsync().Forget());
SetCodeSamples(root,
csharpCode: @"// ========================================
csharpCode: @"// Root 설정 (한 번만)
UTKColorPicker.SetRoot(rootVisualElement);
// ========================================
// 1. Callback 방식
// ========================================
// Alpha 포함 (기본)
var picker = UTKColorPicker.Show(rootVisualElement, Color.white, ""색상 선택"", useAlpha: true);
var picker = UTKColorPicker.Show(Color.white, ""색상 선택"", useAlpha: true);
// 색상 변경 이벤트 (실시간)
picker.OnColorChanged += (color) =>
@@ -458,7 +832,6 @@ picker.OnCancelled += () =>
// Alpha 없이 (RGB만)
var pickerNoAlpha = UTKColorPicker.Show(
rootVisualElement,
Color.red,
""색상 선택 (Alpha 없음)"",
useAlpha: false
@@ -470,7 +843,6 @@ var pickerNoAlpha = UTKColorPicker.Show(
// Alpha 포함
Color result = await UTKColorPicker.ShowAsync(
rootVisualElement,
Color.white,
""색상 선택 (Async)"",
useAlpha: true
@@ -480,7 +852,6 @@ Debug.Log($""선택된 색상: #{ColorUtility.ToHtmlStringRGBA(result)}"");
// Alpha 없이
Color rgbColor = await UTKColorPicker.ShowAsync(
rootVisualElement,
Color.red,
""RGB 색상 선택"",
useAlpha: false
@@ -492,7 +863,6 @@ Debug.Log($""선택된 RGB: #{ColorUtility.ToHtmlStringRGB(rgbColor)}"");
public async UniTask ChangeBackgroundColorAsync()
{
Color newColor = await UTKColorPicker.ShowAsync(
_root,
_currentBackgroundColor,
""배경 색상 선택"",
useAlpha: true
@@ -507,7 +877,7 @@ public async UniTask ChangeBackgroundColorAsync()
{
if (_root == null) return;
var picker = UTKColorPicker.Show(_root, _selectedColor, "Select Color", useAlpha);
var picker = UTKColorPicker.Show(_selectedColor, "Select Color", useAlpha);
picker.OnColorChanged += (color) =>
{
if (_colorPreviewBox != null)
@@ -528,7 +898,7 @@ public async UniTask ChangeBackgroundColorAsync()
{
if (_root == null) return;
Color result = await UTKColorPicker.ShowAsync(_root, _selectedColor, "Select Color (Async)", useAlpha: true);
Color result = await UTKColorPicker.ShowAsync(_selectedColor, "Select Color (Async)", useAlpha: true);
_selectedColor = result;
if (_colorPreviewBox != null)
@@ -543,6 +913,7 @@ public async UniTask ChangeBackgroundColorAsync()
{
if (_root == null) return;
UTKDatePicker.SetRoot(_root);
UTKDatePicker.SetDayNames(new[] { "일", "월", "화", "수", "목", "금", "토" });
_dateLabel = root.Q<Label>("date-label");
@@ -569,7 +940,10 @@ public async UniTask ChangeBackgroundColorAsync()
btnRangeAsync?.RegisterCallback<ClickEvent>(_ => OpenDateRangePickerAsync().Forget());
SetCodeSamples(root,
csharpCode: @"// 요일 이름 설정 (선택사항, 한 번만)
csharpCode: @"// Root 설정 (한 번만)
UTKDatePicker.SetRoot(rootVisualElement);
// 요일 이름 설정 (선택사항, 한 번만)
UTKDatePicker.SetDayNames(new[] { ""일"", ""월"", ""화"", ""수"", ""목"", ""금"", ""토"" });
// ========================================
@@ -578,7 +952,6 @@ UTKDatePicker.SetDayNames(new[] { ""일"", ""월"", ""화"", ""수"", ""목"", "
// Date Only
var datePicker = UTKDatePicker.Show(
rootVisualElement,
DateTime.Today,
UTKDatePicker.PickerMode.DateOnly,
""날짜 선택""
@@ -596,7 +969,6 @@ datePicker.OnCancelled += () =>
// Date & Time
var dateTimePicker = UTKDatePicker.Show(
rootVisualElement,
DateTime.Now,
UTKDatePicker.PickerMode.DateAndTime,
""날짜 및 시간 선택""
@@ -613,7 +985,6 @@ dateTimePicker.OnDateSelected += (date) =>
// Date Only
DateTime? dateResult = await UTKDatePicker.ShowAsync(
rootVisualElement,
DateTime.Today,
UTKDatePicker.PickerMode.DateOnly,
""날짜 선택 (Async)""
@@ -630,7 +1001,6 @@ else
// Date & Time
DateTime? dateTimeResult = await UTKDatePicker.ShowAsync(
rootVisualElement,
DateTime.Now,
UTKDatePicker.PickerMode.DateAndTime,
""날짜 및 시간 선택""
@@ -646,7 +1016,6 @@ if (dateTimeResult.HasValue)
// ========================================
var rangePicker = UTKDatePicker.ShowRange(
rootVisualElement,
DateTime.Today,
DateTime.Today.AddDays(7),
includeTime: false,
@@ -668,7 +1037,6 @@ rangePicker.OnCancelled += () =>
// ========================================
var rangeResult = await UTKDatePicker.ShowRangeAsync(
rootVisualElement,
DateTime.Today,
DateTime.Today.AddDays(7),
includeTime: false,
@@ -686,7 +1054,6 @@ else
// 시간 포함 범위 선택
var rangeTimeResult = await UTKDatePicker.ShowRangeAsync(
rootVisualElement,
DateTime.Now,
DateTime.Now.AddDays(7),
includeTime: true,
@@ -705,7 +1072,7 @@ if (rangeTimeResult.HasValue)
if (_root == null) return;
string title = mode == UTKDatePicker.PickerMode.DateOnly ? "Select Date" : "Select Date & Time";
var picker = UTKDatePicker.Show(_root, _selectedDate, mode, title);
var picker = UTKDatePicker.Show(_selectedDate, mode, title);
picker.OnDateSelected += (date) =>
{
_selectedDate = date;
@@ -723,7 +1090,7 @@ if (rangeTimeResult.HasValue)
{
if (_root == null) return;
DateTime? result = await UTKDatePicker.ShowAsync(_root, _selectedDate, UTKDatePicker.PickerMode.DateOnly, "Select Date (Async)");
DateTime? result = await UTKDatePicker.ShowAsync(_selectedDate, UTKDatePicker.PickerMode.DateOnly, "Select Date (Async)");
if (result.HasValue)
{
@@ -742,7 +1109,7 @@ if (rangeTimeResult.HasValue)
{
if (_root == null) return;
var picker = UTKDatePicker.ShowRange(_root, _rangeStartDate, _rangeEndDate, false, "Select Date Range");
var picker = UTKDatePicker.ShowRange(_rangeStartDate, _rangeEndDate, false, "Select Date Range");
picker.OnDateRangeSelected += (start, end) =>
{
_rangeStartDate = start;
@@ -757,7 +1124,7 @@ if (rangeTimeResult.HasValue)
{
if (_root == null) return;
var result = await UTKDatePicker.ShowRangeAsync(_root, _rangeStartDate, _rangeEndDate, false, "Select Date Range (Async)");
var result = await UTKDatePicker.ShowRangeAsync(_rangeStartDate, _rangeEndDate, false, "Select Date Range (Async)");
if (result.HasValue)
{

View File

@@ -484,6 +484,9 @@ treeWindow.Show();");
container.Add(propertyWindow);
// PropertyTabListWindow 샘플도 함께 초기화 (동일 UXML 내)
InitializePropertyTabListWindowSample(root);
SetCodeSamples(root,
csharpCode: @"// 속성 윈도우 생성
var propertyWindow = new UTKPropertyListWindow();
@@ -547,6 +550,87 @@ propertyWindow.Show();",
</UXML>");
}
private void InitializePropertyTabListWindowSample(VisualElement root)
{
var container = root.Q<VisualElement>("property-tab-list-window-container");
if (container == null) return;
var tabWindow = new UTKPropertyTabListWindow("속성 탭 편집기", showAllTab: true);
tabWindow.ShowCloseButton = true;
tabWindow.style.width = 320;
tabWindow.style.height = 600;
// 이벤트 구독
tabWindow.OnCloseClicked += () =>
{
Debug.Log("PropertyTabListWindow Close clicked");
};
tabWindow.OnTabChanged += (index, tabData) =>
{
Debug.Log($"Tab Changed: index={index}, name={tabData?.Name}");
};
tabWindow.OnPropertyValueChanged += args =>
{
Debug.Log($"Property Changed: {args.PropertyId} = {args.NewValue}");
};
// ===== 탭 1: 기본 속성 (Flat) =====
var generalTab = new TabPropertyData("일반");
generalTab.SetFlatData(new List<IUTKPropertyItem>
{
new UTKStringPropertyItem("name", "Name", "Sample Object"),
new UTKBoolPropertyItem("active", "Is Active", true),
new UTKIntPropertyItem("count", "Count", 10, 0, 100, useSlider: true),
new UTKFloatPropertyItem("speed", "Speed", 1.5f, 0f, 10f, useSlider: true, useStepper: true),
new UTKDropdownPropertyItem("type", "Type",
new List<string> { "Static", "Dynamic", "Kinematic" }, "Static"),
});
// ===== 탭 2: Transform (Grouped) =====
var transformTab = new TabPropertyData("트랜스폼");
var posGroup = new UTKPropertyGroup("position", "Position");
posGroup.AddItem(new UTKVector3PropertyItem("pos", "Position", Vector3.zero));
posGroup.AddItem(new UTKVector3PropertyItem("rot", "Rotation", Vector3.zero));
posGroup.AddItem(new UTKVector3PropertyItem("scl", "Scale", Vector3.one));
var physicsGroup = new UTKPropertyGroup("physics", "Physics");
physicsGroup.AddItem(new UTKFloatPropertyItem("mass", "Mass", 1.0f, 0f, 100f, useSlider: true));
physicsGroup.AddItem(new UTKBoolPropertyItem("gravity", "Use Gravity", true));
physicsGroup.AddItem(new UTKDropdownPropertyItem("collision", "Collision",
new List<string> { "Discrete", "Continuous", "ContinuousDynamic" }, "Discrete"));
transformTab.SetGroupedData(new List<IUTKPropertyGroup> { posGroup, physicsGroup });
// ===== 탭 3: 외형 (Mixed) =====
var appearanceTab = new TabPropertyData("외형");
var mixedEntries = new List<IUTKPropertyEntry>
{
new UTKColorPropertyItem("mainColor", "Main Color", Color.blue),
new UTKColorPropertyItem("emissionColor", "Emission", Color.yellow, useAlpha: true),
new UTKFloatPropertyItem("alpha", "Alpha", 1f, 0f, 1f, useSlider: true),
};
var materialGroup = new UTKPropertyGroup("material", "Material");
materialGroup.AddItem(new UTKStringPropertyItem("shader", "Shader", "Standard"));
materialGroup.AddItem(new UTKDropdownPropertyItem("renderQueue", "Render Queue",
new List<string> { "Geometry", "AlphaTest", "Transparent" }, "Geometry"));
mixedEntries.Add(materialGroup);
appearanceTab.SetMixedData(mixedEntries);
// ===== 탭 4: 비활성 탭 =====
var disabledTab = new TabPropertyData("비활성") { IsEnabled = false, Tooltip = "이 탭은 비활성 상태입니다" };
disabledTab.SetFlatData(new List<IUTKPropertyItem>());
// 탭 데이터 설정
tabWindow.SetTabData(new List<TabPropertyData> { generalTab, transformTab, appearanceTab, disabledTab });
tabWindow.Show();
container.Add(tabWindow);
}
/// <summary>
/// 모든 PropertyItem 종류를 포함하는 샘플 데이터를 생성합니다.
/// </summary>

View File

@@ -97,6 +97,8 @@ public partial class UTKStyleGuideSample : MonoBehaviour
["UTKAlert"] = "UIToolkit/Sample/Modal/UTKAlertSample",
["UTKToast"] = "UIToolkit/Sample/Modal/UTKToastSample",
["UTKTooltip"] = "UIToolkit/Sample/Modal/UTKTooltipSample",
["UTKNotification"] = "UIToolkit/Sample/Modal/UTKNotificationSample",
["UTKModal"] = "UIToolkit/Sample/Modal/UTKModalSample",
// Picker
["UTKColorPicker"] = "UIToolkit/Sample/Picker/UTKColorPickerSample",
["UTKDatePicker"] = "UIToolkit/Sample/Picker/UTKDatePickerSample",
@@ -124,7 +126,7 @@ public partial class UTKStyleGuideSample : MonoBehaviour
["List"] = new[] { "UTKListView", "UTKTreeView", "UTKMultiColumnListView", "UTKMultiColumnTreeView", "UTKFoldout", "UTKScrollView" },
["Card"] = new[] { "UTKCard", "UTKPanel" },
["Tab"] = new[] { "UTKTabView" },
["Modal"] = new[] { "UTKAlert", "UTKToast", "UTKTooltip" },
["Modal"] = new[] { "UTKAlert", "UTKToast", "UTKTooltip", "UTKNotification", "UTKModal" },
["Picker"] = new[] { "UTKColorPicker", "UTKDatePicker" },
["Menu"] = new[] { "UTKTopMenu" },
["ToolBar"] = new[] { "UTKToolBar" },
@@ -546,6 +548,12 @@ public partial class UTKStyleGuideSample : MonoBehaviour
case "UTKTooltip":
InitializeTooltipSample(root);
break;
case "UTKNotification":
InitializeNotificationSample(root);
break;
case "UTKModal":
InitializeModalSample(root);
break;
// Picker
case "UTKColorPicker":
InitializeColorPickerSample(root);