#nullable enable using System; using System.Collections.Generic; using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.UIElements; using UVC.UIToolkit; /// /// UTKStyleGuideSample의 Modal, Tab, Picker 카테고리 Initialize 메서드들 /// public partial class UTKStyleGuideSample { #region Tab Initializer private void InitializeTabViewSample(VisualElement root) { // Top Alignment (기본) var tabContainerTop = root.Q("tabview-top-container"); if (tabContainerTop != null) { var tabView = new UTKTabView(); tabView.Align = TabAlign.Top; tabView.style.width = 500; tabView.style.height = 200; tabView.AddUTKTab("일반", new Label("일반 설정 내용입니다.\n탭이 위쪽에 배치됩니다.")); tabView.AddUTKTab("고급", new Label("고급 설정 내용입니다.")).SetMaterialIcon(UTKMaterialIcons.Tune); tabView.AddUTKTab("정보", new Label("정보 탭 내용입니다.")).SetMaterialIcon(UTKMaterialIcons.Info); tabView.AddUTKTab("알림", new Label("알림 설정 내용입니다.")).SetMaterialIcon(UTKMaterialIcons.Notifications); tabContainerTop.Add(tabView); } // Bottom Alignment var tabContainerBottom = root.Q("tabview-bottom-container"); if (tabContainerBottom != null) { var tabView = new UTKTabView(); tabView.Align = TabAlign.Bottom; tabView.style.width = 500; tabView.style.height = 200; tabView.AddUTKTab("일반", new Label("일반 설정 내용입니다.\n탭이 아래쪽에 배치됩니다.")); tabView.AddUTKTab("고급", new Label("고급 설정 내용입니다.")).SetMaterialIcon(UTKMaterialIcons.Tune); tabView.AddUTKTab("정보", new Label("정보 탭 내용입니다.")).SetMaterialIcon(UTKMaterialIcons.Info); tabContainerBottom.Add(tabView); } // Left Alignment var tabContainerLeft = root.Q("tabview-left-container"); if (tabContainerLeft != null) { var tabView = new UTKTabView(); tabView.Align = TabAlign.Left; tabView.style.width = 500; tabView.style.height = 200; tabView.AddUTKTab("일반", new Label("일반 설정 내용입니다.\n탭이 왼쪽에 세로로 배치됩니다.")).SetMaterialIcon(UTKMaterialIcons.Home); tabView.AddUTKTab("고급", new Label("고급 설정 내용입니다.")).SetMaterialIcon(UTKMaterialIcons.Tune); tabView.AddUTKTab("정보", new Label("정보 탭 내용입니다.")); tabContainerLeft.Add(tabView); } // Right Alignment var tabContainerRight = root.Q("tabview-right-container"); if (tabContainerRight != null) { var tabView = new UTKTabView(); tabView.Align = TabAlign.Right; tabView.style.width = 500; tabView.style.height = 200; tabView.AddUTKTab("일반", new Label("일반 설정 내용입니다.\n탭이 오른쪽에 세로로 배치됩니다.")).SetImageIcon(UTKImageIcons.BtnCancel64); tabView.AddUTKTab("고급", new Label("고급 설정 내용입니다.")); tabView.AddUTKTab("정보", new Label("정보 탭 내용입니다.")).SetMaterialIcon(UTKMaterialIcons.Info); tabContainerRight.Add(tabView); } SetCodeSamples(root, csharpCode: @"// 기본 사용법 (Top Alignment) var tabView = new UTKTabView(); tabView.Align = TabAlign.Top; // 기본값 tabView.style.width = 500; tabView.style.height = 200; // 탭 추가 (아이콘 없음) tabView.AddUTKTab(""일반"", new Label(""일반 설정 내용"")); // Material Icon 탭 tabView.AddUTKTab(""고급"", new Label(""고급 설정 내용"")).SetMaterialIcon(UTKMaterialIcons.Tune); tabView.AddUTKTab(""정보"", new Label(""정보 탭 내용"")).SetMaterialIcon(UTKMaterialIcons.Info); tabView.AddUTKTab(""알림"", new Label(""알림 설정 내용"")).SetMaterialIcon(UTKMaterialIcons.Notifications); // Bottom Alignment - 탭이 아래쪽에 배치 var tabViewBottom = new UTKTabView(); tabViewBottom.Align = TabAlign.Bottom; tabViewBottom.AddUTKTab(""Tab 1"", new Label(""Content 1"")); // Left Alignment - 탭이 왼쪽에 세로로 배치 var tabViewLeft = new UTKTabView(); tabViewLeft.Align = TabAlign.Left; tabViewLeft.AddUTKTab(""Tab 1"", new Label(""Content 1"")); // Right Alignment - 탭이 오른쪽에 세로로 배치 var tabViewRight = new UTKTabView(); tabViewRight.Align = TabAlign.Right; tabViewRight.AddUTKTab(""Tab 1"", new Label(""Content 1"")); // 복잡한 콘텐츠 추가 var contentContainer = new VisualElement(); contentContainer.Add(new Label(""복잡한 콘텐츠"")); contentContainer.Add(new UTKButton(""버튼"")); tabView.AddUTKTab(""Tab 4"", contentContainer); // 탭 변경 이벤트 tabView.OnTabChanged += (index, tab) => { Debug.Log($""선택된 탭 인덱스: {index}""); }; // 프로그램으로 탭 선택 tabView.SelectedIndex = 1; // 두 번째 탭 선택 // 현재 선택된 탭 인덱스 var currentTab = tabView.SelectedIndex;", uxmlCode: @" "); } #endregion #region Modal Initializers private void InitializeAlertSample(VisualElement root) { if (_root == null) return; UTKAlert.SetRoot(_root); var btnInfo = root.Q("btn-info"); btnInfo?.RegisterCallback(_ => ShowInfoAlertAsync().Forget()); var btnSuccess = root.Q("btn-success"); btnSuccess?.RegisterCallback(_ => ShowSuccessAlertAsync().Forget()); var btnWarning = root.Q("btn-warning"); btnWarning?.RegisterCallback(_ => ShowWarningAlertAsync().Forget()); var btnError = root.Q("btn-error"); btnError?.RegisterCallback(_ => ShowErrorAlertAsync().Forget()); var btnConfirm = root.Q("btn-confirm"); btnConfirm?.RegisterCallback(_ => ShowConfirmAlertAsync().Forget()); var btnConfirmCustom = root.Q("btn-confirm-custom"); btnConfirmCustom?.RegisterCallback(_ => ShowConfirmCustomLabelsAsync().Forget()); var btnCallback = root.Q("btn-callback"); btnCallback?.RegisterCallback(_ => { UTKAlert.ShowInfo("Callback Style", "This uses callback instead of async.", onClose: () => Debug.Log("Alert closed via callback")); }); var btnConfirmCallback = root.Q("btn-confirm-callback"); btnConfirmCallback?.RegisterCallback(_ => { UTKAlert.ShowConfirm("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(""정보"", ""콜백 방식입니다."", onClose: () => Debug.Log(""Alert가 닫혔습니다."")); // Confirm with Callback UTKAlert.ShowConfirm(""확인"", ""진행하시겠습니까?"", 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("btn-toast-info"); btnInfo?.RegisterCallback(_ => UTKToast.Show("This is an info toast!")); var btnSuccess = root.Q("btn-toast-success"); btnSuccess?.RegisterCallback(_ => UTKToast.ShowSuccess("Operation successful!")); var btnWarning = root.Q("btn-toast-warning"); btnWarning?.RegisterCallback(_ => UTKToast.ShowWarning("Warning: Check your input!")); var btnError = root.Q("btn-toast-error"); btnError?.RegisterCallback(_ => 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("btn-short-tooltip"); if (btnShort != null) { UTKTooltipManager.Instance.AttachTooltip(btnShort, "This is a short tooltip."); } var btnLong = root.Q("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."); } SetCodeSamples(root, csharpCode: @"// 1. 버튼에 툴팁 연결 var saveButton = new UTKButton("""", UTKMaterialIcons.Save); UTKTooltipManager.Instance.AttachTooltip(saveButton, ""저장 (Ctrl+S)""); // 2. 다국어 키로 툴팁 연결 UTKTooltipManager.Instance.AttachTooltip(settingsButton, ""tooltip_settings""); // 4. 아이콘 버튼에 툴팁 var deleteBtn = new UTKButton("""", UTKMaterialIcons.Delete) { IconOnly = true }; UTKTooltipManager.Instance.AttachTooltip(deleteBtn, ""삭제""); // 5. 툴팁 업데이트 UTKTooltipManager.Instance.UpdateTooltip(button, ""새로운 설명""); // 6. 툴팁 제거 UTKTooltipManager.Instance.DetachTooltip(button); // 7. 즉시 표시 (특정 위치에) UTKTooltipManager.Instance.Show(""임시 정보"", new Vector2(100, 200)); // 8. 숨기기 UTKTooltipManager.Instance.Hide(); // 9. 여러 요소에 툴팁 연결 var buttons = new[] { btn1, btn2, btn3 }; var tooltips = new[] { ""버튼 1"", ""버튼 2"", ""버튼 3"" }; for (int i = 0; i < buttons.Length; i++) { UTKTooltipManager.Instance.AttachTooltip(buttons[i], tooltips[i]); }"); } #endregion #region Modal Initializers (UTKModal) private void InitializeModalSample(VisualElement root) { if (_root == null) return; UTKModal.SetRoot(_root); // Modal Sizes var btnSmall = root.Q("btn-modal-small"); btnSmall?.RegisterCallback(_ => ShowModalWithSize(UTKModal.ModalSize.Small)); var btnMedium = root.Q("btn-modal-medium"); btnMedium?.RegisterCallback(_ => ShowModalWithSize(UTKModal.ModalSize.Medium)); var btnLarge = root.Q("btn-modal-large"); btnLarge?.RegisterCallback(_ => ShowModalWithSize(UTKModal.ModalSize.Large)); var btnFullScreen = root.Q("btn-modal-fullscreen"); btnFullScreen?.RegisterCallback(_ => ShowModalWithSize(UTKModal.ModalSize.FullScreen)); // Options var btnFooter = root.Q("btn-modal-footer"); btnFooter?.RegisterCallback(_ => { var modal = UTKModal.Create("푸터 버튼 모달", UTKModal.ModalSize.Medium); modal.Add(new Label("확인 또는 취소를 선택하세요.")); var confirmBtn = new UTKButton("확인") { Variant = UTKButton.ButtonVariant.Primary }; confirmBtn.RegisterCallback(_ => { Debug.Log("Modal confirmed"); modal.Close(); }); var cancelBtn = new UTKButton("취소") { Variant = UTKButton.ButtonVariant.Normal }; cancelBtn.RegisterCallback(_ => { Debug.Log("Modal cancelled"); modal.Close(); }); modal.AddToFooter(cancelBtn); modal.AddToFooter(confirmBtn); modal.Show(); }); var btnNoClose = root.Q("btn-modal-no-close"); btnNoClose?.RegisterCallback(_ => { var modal = UTKModal.Create("닫기 버튼 없음", UTKModal.ModalSize.Small); modal.ShowCloseButton = false; modal.CloseOnBackdropClick = true; modal.Add(new Label("닫기 버튼이 없습니다.\n배경을 클릭하면 닫힙니다.")); modal.Show(); }); var btnNoBackdrop = root.Q("btn-modal-no-backdrop"); btnNoBackdrop?.RegisterCallback(_ => { var modal = UTKModal.Create("배경 클릭 비활성화", UTKModal.ModalSize.Small); modal.CloseOnBackdropClick = false; modal.Add(new Label("배경을 클릭해도 닫히지 않습니다.\nX 버튼으로만 닫을 수 있습니다.")); modal.Show(); }); // Custom Content - Form Modal var btnForm = root.Q("btn-modal-form"); btnForm?.RegisterCallback(_ => { var modal = UTKModal.Create("사용자 정보 입력", 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(_ => { Debug.Log($"Name: {nameField.value}, Email: {emailField.value}"); modal.Close(); }); var cancelBtn = new UTKButton("취소") { Variant = UTKButton.ButtonVariant.Normal }; cancelBtn.RegisterCallback(_ => modal.Close()); modal.AddToFooter(cancelBtn); modal.AddToFooter(submitBtn); modal.Show(); }); SetCodeSamples(root, csharpCode: @"// Root 설정 (한 번만) UTKModal.SetRoot(rootVisualElement); // ======================================== // 1. 기본 모달 표시 // ======================================== var modal = UTKModal.Create(""제목"", UTKModal.ModalSize.Medium); modal.Add(new Label(""모달 내용"")); // 닫힘 이벤트 modal.OnClosed += () => Debug.Log(""모달 닫힘""); // 화면에 표시 modal.Show(); // ======================================== // 2. 모달 크기 // ======================================== // Small var small = UTKModal.Create(""Small"", UTKModal.ModalSize.Small); small.Show(); // Medium (기본) var medium = UTKModal.Create(""Medium"", UTKModal.ModalSize.Medium); medium.Show(); // Large var large = UTKModal.Create(""Large"", UTKModal.ModalSize.Large); large.Show(); // FullScreen var full = UTKModal.Create(""FullScreen"", UTKModal.ModalSize.FullScreen); full.Show(); // ======================================== // 3. 옵션 설정 // ======================================== var modal = UTKModal.Create(""설정""); // 닫기 버튼 숨기기 modal.ShowCloseButton = false; // 배경 클릭 시 닫기 비활성화 modal.CloseOnBackdropClick = false; // 푸터 숨기기 modal.SetFooterVisible(false); // 옵션 설정 후 표시 modal.Show(); // ======================================== // 4. 푸터 버튼 추가 // ======================================== var modal = UTKModal.Create(""확인 모달""); modal.Add(new Label(""정말 삭제하시겠습니까?"")); var confirmBtn = new UTKButton(""삭제"") { Variant = UTKButton.ButtonVariant.Danger }; confirmBtn.RegisterCallback(_ => { Debug.Log(""삭제 실행""); modal.Close(); }); var cancelBtn = new UTKButton(""취소"") { Variant = UTKButton.ButtonVariant.Normal }; cancelBtn.RegisterCallback(_ => modal.Close()); modal.AddToFooter(cancelBtn); modal.AddToFooter(confirmBtn); modal.Show(); // ======================================== // 5. 폼 모달 // ======================================== var modal = UTKModal.Create(""사용자 정보""); var nameField = new UTKInputField(""이름""); var emailField = new UTKInputField(""이메일""); modal.Add(nameField); modal.Add(emailField); var submitBtn = new UTKButton(""제출"") { Variant = UTKButton.ButtonVariant.Primary }; submitBtn.RegisterCallback(_ => { Debug.Log($""Name: {nameField.value}, Email: {emailField.value}""); modal.Close(); }); modal.AddToFooter(submitBtn); modal.Show(); // ======================================== // 6. 프로그래밍 방식 닫기 // ======================================== var modal = UTKModal.Create(""타이머 모달""); modal.Add(new Label(""3초 후 자동으로 닫힙니다."")); modal.ShowCloseButton = false; modal.CloseOnBackdropClick = false; modal.Show(); // 3초 후 닫기 modal.schedule.Execute(() => modal.Close()).StartingIn(3000); // ======================================== // 7. Async/Await 방식 (닫힐 때까지 대기) // ======================================== var modal = UTKModal.Create(""설정""); modal.Add(new Label(""모달 내용"")); var closeBtn = new UTKButton(""닫기"") { Variant = UTKButton.ButtonVariant.Primary }; closeBtn.OnClicked += () => modal.Close(); modal.AddToFooter(closeBtn); // 모달이 닫힐 때까지 대기 await modal.ShowAsync(); Debug.Log(""모달이 닫혔습니다.""); // Async 폼 예시 var formModal = UTKModal.Create(""사용자 정보""); var nameField = new UTKInputField(""이름""); formModal.Add(nameField); var submitBtn = new UTKButton(""제출"") { Variant = UTKButton.ButtonVariant.Primary }; submitBtn.OnClicked += () => formModal.Close(); formModal.AddToFooter(submitBtn); await formModal.ShowAsync(); Debug.Log($""입력된 이름: {nameField.value}""); // ======================================== // 8. IUTKModalContent 결과 반환 // ======================================== // IUTKModalContent를 구현한 콘텐츠 클래스 정의 // public class UserFormContent : VisualElement, IUTKModalContent // { // private UTKInputField _nameField = new(""이름""); // private UTKInputField _emailField = new(""이메일""); // // public UserFormContent() // { // Add(_nameField); // Add(_emailField); // } // // public UserData? GetResult() // { // return new UserData(_nameField.value, _emailField.value); // } // } // 사용 var modal = UTKModal.Create(""사용자 정보""); var form = new UserFormContent(); modal.Add(form); var submitBtn = new UTKButton(""제출"") { Variant = UTKButton.ButtonVariant.Primary }; submitBtn.OnClicked += () => modal.Close(); modal.AddToFooter(submitBtn); // Close() 시 자동으로 form.GetResult() 호출 UserData? result = await modal.ShowAsync(); if (result != null) Debug.Log($""이름: {result.Name}, 이메일: {result.Email}"");", uxmlCode: @" "); } private void ShowModalWithSize(UTKModal.ModalSize size) { if (_root == null) return; var modal = UTKModal.Create($"{size} Modal", size); modal.Add(new Label($"이것은 {size} 크기의 모달입니다.")); modal.OnClosed += () => Debug.Log($"{size} modal closed"); modal.Show(); } #endregion #region Loading Initializers private void InitializeLoadingSample(VisualElement root) { if (_root == null) return; UTKLoading.SetRoot(_root); // Static API 버튼 var btnShow = root.Q("btn-show"); btnShow?.RegisterCallback(_ => UTKLoading.Show()); var btnShowFast = root.Q("btn-show-fast"); btnShowFast?.RegisterCallback(_ => UTKLoading.Show(speed: 2f)); var btnShowSlow = root.Q("btn-show-slow"); btnShowSlow?.RegisterCallback(_ => UTKLoading.Show(speed: 0.5f)); var btnHide = root.Q("btn-hide"); btnHide?.RegisterCallback(_ => UTKLoading.Hide()); // UXML 인라인 스피너 크기 커스터마이징 (Size 속성으로 지정) var loadingSmall = root.Q("loading-small"); if (loadingSmall != null) { loadingSmall.Size = 32f; loadingSmall.Thickness = 3f; } var loadingLarge = root.Q("loading-large"); if (loadingLarge != null) { loadingLarge.Size = 72f; loadingLarge.Thickness = 6f; } SetCodeSamples(root, csharpCode: @"// ======================================== // Static API (전체 화면 로딩 + Blocker) // ======================================== // Root 설정 (한 번만) UTKLoading.SetRoot(rootVisualElement); // 기본 속도로 표시 (색상은 테마 --color-primary 자동 적용) UTKLoading.Show(); // 속도 배율 지정 (1.0 = 기본 속도) UTKLoading.Show(speed: 2.0f); // 빠르게 UTKLoading.Show(speed: 0.5f); // 느리게 // 이미 표시 중이면 중복 생성 없이 기존 인스턴스 반환 var loading = UTKLoading.Show(); // 숨기기 (애니메이션 정지 + 제거) UTKLoading.Hide(); // 현재 표시 여부 확인 bool isShowing = UTKLoading.IsShowing; // ======================================== // 실제 사용 예시 // ======================================== public async UniTask LoadDataAsync(CancellationToken ct) { UTKLoading.Show(); try { await FetchDataFromServerAsync(ct); } finally { UTKLoading.Hide(); // 성공/실패 모두 숨김 } }", uxmlCode: @" "); } #endregion #region Notification Initializers private void InitializeNotificationSample(VisualElement root) { if (_root == null) return; UTKNotification.SetRoot(_root); // Notification Types var btnInfo = root.Q("btn-noti-info"); btnInfo?.RegisterCallback(_ => UTKNotification.ShowInfo("정보", "이것은 정보 알림입니다.")); var btnSuccess = root.Q("btn-noti-success"); btnSuccess?.RegisterCallback(_ => UTKNotification.ShowSuccess("성공", "작업이 성공적으로 완료되었습니다!")); var btnWarning = root.Q("btn-noti-warning"); btnWarning?.RegisterCallback(_ => UTKNotification.ShowWarning("경고", "주의가 필요한 상황입니다.")); var btnError = root.Q("btn-noti-error"); btnError?.RegisterCallback(_ => UTKNotification.ShowError("오류", "오류가 발생했습니다!")); // Position var btnTopLeft = root.Q("btn-noti-top-left"); btnTopLeft?.RegisterCallback(_ => UTKNotification.Show("Top Left", "TopLeft 위치 알림", UTKNotification.NotificationType.Info, UTKNotification.NotificationPosition.TopLeft)); var btnTopRight = root.Q("btn-noti-top-right"); btnTopRight?.RegisterCallback(_ => UTKNotification.Show("Top Right", "TopRight 위치 알림", UTKNotification.NotificationType.Info, UTKNotification.NotificationPosition.TopRight)); var btnBottomLeft = root.Q("btn-noti-bottom-left"); btnBottomLeft?.RegisterCallback(_ => UTKNotification.Show("Bottom Left", "BottomLeft 위치 알림", UTKNotification.NotificationType.Info, UTKNotification.NotificationPosition.BottomLeft)); var btnBottomRight = root.Q("btn-noti-bottom-right"); btnBottomRight?.RegisterCallback(_ => UTKNotification.Show("Bottom Right", "BottomRight 위치 알림", UTKNotification.NotificationType.Info, UTKNotification.NotificationPosition.BottomRight)); // With Actions var btnAction = root.Q("btn-noti-action"); btnAction?.RegisterCallback(_ => { 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("btn-noti-persistent"); btnPersistent?.RegisterCallback(_ => { 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("color-preview-box"); _colorHexLabel = root.Q