디자인 변경 중
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using SampleProject;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
@@ -7,7 +7,6 @@ using UnityEngine.UI;
|
||||
using UVC.Factory.Component;
|
||||
using UVC.Locale;
|
||||
using UVC.UI.Modal;
|
||||
|
||||
namespace UVC.Factory.Buttons
|
||||
{
|
||||
public class UISearchInput : MonoBehaviour
|
||||
@@ -43,6 +42,7 @@ namespace UVC.Factory.Buttons
|
||||
});
|
||||
|
||||
inputField.onEndEdit.AddListener(OnFindLocation);
|
||||
inputField.onSubmit.AddListener(OnFindLocation);
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
8
Assets/Scripts/UVC/UI/Buttons.meta
Normal file
8
Assets/Scripts/UVC/UI/Buttons.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 28c2743eed2320646baf3f2ad2dd307a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
130
Assets/Scripts/UVC/UI/Buttons/ImageButton.cs
Normal file
130
Assets/Scripts/UVC/UI/Buttons/ImageButton.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace UVC.UI.Buttons
|
||||
{
|
||||
/// <summary>
|
||||
/// 이미지 color를 변경하여 버튼과 같은 UI 요소에 시각적 피드백을 제공하는 이미지 버튼입니다.
|
||||
/// </summary>
|
||||
public class ImageButton : Image, IPointerDownHandler, IPointerUpHandler,
|
||||
IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
|
||||
{
|
||||
[SerializeField]
|
||||
private Color originalColor = Color.white; // 기본 상태일 때의 색상
|
||||
[SerializeField]
|
||||
private Color hoverColor = Color.gray; // 마우스 포인터가 위에 있을 때의 색상
|
||||
[SerializeField]
|
||||
private Color clickColor = Color.gray; // 클릭했을 때의 색상
|
||||
[SerializeField]
|
||||
private Color disabledColor = Color.gray; // 비활성화 상태일 때의 색상
|
||||
|
||||
[SerializeField]
|
||||
private bool interactable = true;
|
||||
public bool Interactable
|
||||
{
|
||||
get => interactable;
|
||||
set
|
||||
{
|
||||
if (interactable == value) return;
|
||||
interactable = value;
|
||||
raycastTarget = value; // 상호 작용 가능 상태에 따라 raycastTarget 설정
|
||||
color = value ? originalColor : disabledColor;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
/// <summary>
|
||||
/// 버튼 클릭 이벤트에 대한 함수 정의.
|
||||
/// </summary>
|
||||
public class ButtonClickedEvent : UnityEvent { }
|
||||
|
||||
// onClick 이벤트는 인스펙터에 노출되며, 버튼 클릭 시 호출될 함수를 등록할 수 있습니다.
|
||||
[FormerlySerializedAs("onClick")]
|
||||
[SerializeField]
|
||||
private ButtonClickedEvent m_OnClick = new ButtonClickedEvent();
|
||||
|
||||
/// <summary>
|
||||
/// 버튼을 클릭할 때마다 호출되는 UnityEvent입니다.
|
||||
/// </summary>
|
||||
public ButtonClickedEvent onClick
|
||||
{
|
||||
get { return m_OnClick; }
|
||||
set { m_OnClick = value; }
|
||||
}
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
// 초기화 시 Interactable 프로퍼티를 통해 색상과 raycastTarget을 설정합니다.
|
||||
raycastTarget = interactable;
|
||||
color = interactable ? originalColor : disabledColor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 포인터가 버튼을 눌렀을 때 호출됩니다.
|
||||
/// </summary>
|
||||
public virtual void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
if (Interactable)
|
||||
{
|
||||
color = clickColor; // 클릭 시 컬러 변경
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 포인터가 버튼 영역에 들어왔을 때 호출됩니다.
|
||||
/// </summary>
|
||||
public virtual void OnPointerEnter(PointerEventData eventData)
|
||||
{
|
||||
if (Interactable)
|
||||
{
|
||||
color = hoverColor; // 마우스 오버 시 컬러 변경
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 포인터가 버튼 영역을 벗어났을 때 호출됩니다.
|
||||
/// </summary>
|
||||
public virtual void OnPointerExit(PointerEventData eventData)
|
||||
{
|
||||
// 상호작용 가능 여부와 관계없이 포인터가 나가면 상태에 맞는 기본 색상으로 돌아갑니다.
|
||||
color = interactable ? originalColor : disabledColor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 포인터가 버튼에서 떼어졌을 때 호출됩니다.
|
||||
/// </summary>
|
||||
public virtual void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
if (Interactable)
|
||||
{
|
||||
color = hoverColor; // 클릭 후 원래 컬러로 변경
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 버튼 클릭이 완료되었을 때 호출됩니다. (PointerDown과 PointerUp이 같은 대상에서 발생)
|
||||
/// </summary>
|
||||
public virtual void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
// 왼쪽 마우스 버튼 클릭이 아니면 무시합니다.
|
||||
if (eventData.button != PointerEventData.InputButton.Left) return;
|
||||
Press();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 내부적으로 클릭 이벤트를 실행합니다.
|
||||
/// </summary>
|
||||
private void Press()
|
||||
{
|
||||
// 컴포넌트가 활성화 상태가 아니거나 상호작용 불가능하면 이벤트를 호출하지 않습니다.
|
||||
if (!IsActive() || !interactable) return;
|
||||
m_OnClick.Invoke();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/UVC/UI/Buttons/ImageButton.cs.meta
Normal file
2
Assets/Scripts/UVC/UI/Buttons/ImageButton.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4185643eda515744385d49b83fe88dce
|
||||
43
Assets/Scripts/UVC/UI/Commands/MinimizeApplicationCommand.cs
Normal file
43
Assets/Scripts/UVC/UI/Commands/MinimizeApplicationCommand.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
#nullable enable
|
||||
using UnityEngine;
|
||||
#if UNITY_STANDALONE_WIN
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
|
||||
namespace UVC.UI.Commands
|
||||
{
|
||||
public class MinimizeApplicationCommand : ICommand
|
||||
{
|
||||
|
||||
#if UNITY_STANDALONE_WIN
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr GetActiveWindow();
|
||||
|
||||
private const int SW_MINIMIZE = 6;
|
||||
#endif
|
||||
|
||||
public void Execute(object? parameter = null)
|
||||
{
|
||||
// 파라미터는 여기서는 사용되지 않을 수 있음
|
||||
if (parameter != null)
|
||||
{
|
||||
Debug.Log($"MinimizeApplicationCommand 실행됨 (파라미터 무시됨: {parameter})");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("MinimizeApplicationCommand 실행됨");
|
||||
}
|
||||
|
||||
#if UNITY_STANDALONE_WIN
|
||||
ShowWindow(GetActiveWindow(), SW_MINIMIZE);
|
||||
#else
|
||||
Debug.Log("창 최소화는 Windows 독립 실행형에서만 지원됩니다.");
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: def4dca38129c4d4fb17f819b3e799bf
|
||||
@@ -0,0 +1,13 @@
|
||||
using UVC.UI.Commands;
|
||||
using UVC.UI.Commands.Mono;
|
||||
|
||||
namespace Assets.Scripts.UVC.UI.Commands.Mono
|
||||
{
|
||||
internal class MinimizeApplicationCommandMono : MonoBehaviourCommand
|
||||
{
|
||||
public override void Execute()
|
||||
{
|
||||
new MinimizeApplicationCommand().Execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3c6fc4cbf58b35409c0bbd44175ecec
|
||||
@@ -236,7 +236,7 @@ namespace UVC.UI.Menu
|
||||
new MenuItemData("confirm", "Confirm", new ActionCommand(async () => {
|
||||
bool result = await Confirm.Show("확인", "이것은 간단한 알림 메시지입니다.");
|
||||
ULog.Debug($"사용자가 확인 버튼을 눌렀나요? {result}");
|
||||
result = await Confirm.Show("경고", "데이터를 저장할 수 없습니다.", "알겠습니다", "아니요");
|
||||
result = await Confirm.Show("경고", "데이터를 저장할 수 없습니다.", "알겠습니다~~~~", "아니요");
|
||||
ULog.Debug($"사용자가 알림을 확인했나요? {result}");
|
||||
result = await Confirm.Show("error", "error_network_not", "button_retry", "button_cancel");
|
||||
ULog.Debug($"사용자가 네트워크 오류 알림을 확인했나요? {result}");
|
||||
|
||||
@@ -3,6 +3,7 @@ using Cysharp.Threading.Tasks;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UVC.Extention;
|
||||
using UVC.Log;
|
||||
|
||||
namespace UVC.UI.Modal
|
||||
@@ -128,6 +129,18 @@ namespace UVC.UI.Modal
|
||||
if (messageText != null && content != null)
|
||||
{
|
||||
messageText.text = content.Message;
|
||||
if(titleText != null)
|
||||
{
|
||||
// 메시지 텍스트의 위치를 제목 아래로 조정해요. messageText를 titleText 높이 + 14만큼 아래로 이동시켜요.
|
||||
RectTransform messageRect = messageText.GetComponent<RectTransform>();
|
||||
if (messageRect != null)
|
||||
{
|
||||
float preferredHeight = titleText.preferredHeight;
|
||||
Vector2 anchoredPosition = titleText.rectTransform.anchoredPosition;
|
||||
float newY = anchoredPosition.y - (content.Title.IsNullOrEmpty() ? 0 : preferredHeight + 14);
|
||||
messageRect.anchoredPosition = new Vector2(messageRect.anchoredPosition.x, newY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 확인 버튼 설정
|
||||
@@ -137,6 +150,25 @@ namespace UVC.UI.Modal
|
||||
if (content.ShowConfirmButton && confirmButtonText != null && !string.IsNullOrEmpty(content.ConfirmButtonText))
|
||||
{
|
||||
confirmButtonText.text = content.ConfirmButtonText;
|
||||
// text가 너무 길면 버튼 크기를 조정해요.
|
||||
RectTransform confirmButtonRect = confirmButton.GetComponent<RectTransform>();
|
||||
if (confirmButtonRect != null && confirmButtonText.preferredWidth > confirmButtonRect.sizeDelta.x - 10)
|
||||
{
|
||||
// 버튼의 너비를 글자 크기에 맞춰 조정해요.
|
||||
confirmButtonRect.sizeDelta = new Vector2(confirmButtonText.preferredWidth + 20, confirmButtonRect.sizeDelta.y);
|
||||
|
||||
//취소 버튼이 null이 아니고, 취소 버튼이 활성화되어 있다면 변경 된 confirmButtonRect에 맞춰 왼쪽으로 이동시켜요.
|
||||
//confirm 버튼과 cancel 버튼 간격은 12
|
||||
if (cancelButton != null && content.ShowCancelButton)
|
||||
{
|
||||
RectTransform cancelButtonRect = cancelButton.GetComponent<RectTransform>();
|
||||
if (cancelButtonRect != null)
|
||||
{
|
||||
// confirm 버튼의 왼쪽에 cancel 버튼을 배치해요.
|
||||
cancelButtonRect.anchoredPosition = new Vector2(confirmButtonRect.anchoredPosition.x - confirmButtonRect.sizeDelta.x - 12, cancelButtonRect.anchoredPosition.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,6 +179,13 @@ namespace UVC.UI.Modal
|
||||
if (content.ShowCancelButton && cancelButtonText != null && !string.IsNullOrEmpty(content.CancelButtonText))
|
||||
{
|
||||
cancelButtonText.text = content.CancelButtonText;
|
||||
// text가 너무 길면 버튼 크기를 조정해요.
|
||||
RectTransform cancelButtonRect = cancelButton.GetComponent<RectTransform>();
|
||||
if (cancelButtonRect != null && cancelButtonText.preferredWidth > cancelButtonRect.sizeDelta.x - 10)
|
||||
{
|
||||
// 버튼의 너비를 글자 크기에 맞춰 조정해요.
|
||||
cancelButtonRect.sizeDelta = new Vector2(cancelButtonText.preferredWidth + 20, cancelButtonRect.sizeDelta.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,6 +208,7 @@ namespace UVC.UI.Modal
|
||||
/// </summary>
|
||||
protected virtual void AdjustButtonPositions()
|
||||
{
|
||||
return; // 기본 구현은 아무것도 안 해요. 필요하면 재정의해서 사용하세요.
|
||||
bool isConfirmActive = confirmButton != null && confirmButton.gameObject.activeSelf;
|
||||
bool isCancelActive = cancelButton != null && cancelButton.gameObject.activeSelf;
|
||||
|
||||
|
||||
@@ -76,6 +76,9 @@ namespace UVC.UI.Toolbar
|
||||
new ActionCommand(() => Debug.Log("화면 축소 버튼 클릭됨")),
|
||||
"화면을 한 단계 축소 합니다.");
|
||||
|
||||
// 구분선
|
||||
mainToolbar.AddSeparator();
|
||||
|
||||
// RadioButtonGroup 샘플
|
||||
mainToolbar.AddRadioButton("CameraControlGroup", "Top View", true,
|
||||
"Prefabs/UI/Toolbar/images/ic_camera_top_on",
|
||||
@@ -99,7 +102,6 @@ namespace UVC.UI.Toolbar
|
||||
// 구분선
|
||||
mainToolbar.AddSeparator();
|
||||
|
||||
|
||||
// 기존 확장 버튼 (예시로 남겨두거나 필요에 따라 수정/제거)
|
||||
var expandableBtnModel = mainToolbar.AddExpandableButton("button_brush_size",
|
||||
"Prefabs/UI/Toolbar/images/ic_brush_default_white",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
using UVC.Factory.Playback;
|
||||
using UVC.Locale;
|
||||
using UVC.UI.Commands;
|
||||
using UVC.UI.Toolbar;
|
||||
@@ -89,24 +90,60 @@ namespace UVC.UI.ToolBar
|
||||
// --- 툴바 모델 구성 시작 ---
|
||||
// 여기에 다양한 툴바 항목(버튼, 구분선 등)을 mainToolbar 모델에 추가합니다.
|
||||
|
||||
// 예시 1: 카메라 조절 라디오 버튼 그룹
|
||||
// "CameraControlGroup"이라는 이름으로 라디오 버튼 그룹을 만듭니다.
|
||||
// AddRadioButton의 세 번째 파라미터(initialState)는 해당 버튼이 초기에 선택될지 여부입니다.
|
||||
// 각 버튼은 아이콘 경로(선택 시/해제 시), OnToggle 콜백, ClickCommand, 툴팁 키를 가질 수 있습니다.
|
||||
// 컴포넌트 목록
|
||||
mainToolbar.AddStandardButton("컴포넌트 목록",
|
||||
"Prefabs/UI/Toolbar/images/ic_menu_elements",
|
||||
new ActionCommand(() => Debug.Log("컴포넌트 목록 버튼 클릭됨")),
|
||||
"컴포넌트 목록 창을 엽니다.");
|
||||
|
||||
// playback
|
||||
mainToolbar.AddStandardButton("Playback",
|
||||
"Prefabs/UI/Toolbar/images/ic_menu_playback",
|
||||
new PlaybackCommand(),
|
||||
"Playback을 실행 시킵니다.");
|
||||
|
||||
// 화면 캡처
|
||||
mainToolbar.AddStandardButton("button_capture_screen",
|
||||
"Prefabs/UI/Toolbar/images/ic_menu_capture",
|
||||
new ActionCommand(() => Debug.Log("화면 캡처 버튼 클릭됨")),
|
||||
"tooltip_capture_screen");
|
||||
|
||||
// 화면 녹화 시작/중지 (ToggleButton)
|
||||
mainToolbar.AddToggleButton("button_record_screen", false,
|
||||
"Prefabs/UI/Toolbar/images/ic_menu_camera_on",
|
||||
"Prefabs/UI/Toolbar/images/ic_menu_camera_off",
|
||||
(isSelected) => Debug.Log($"화면 녹화 상태: {(isSelected ? "녹화 중" : "중지")} (OnToggle 콜백)"),
|
||||
new ActionCommand<bool>((isRecording) => Debug.Log($"화면 녹화 Command 실행: {(isRecording ? "녹화 시작" : "녹화 중지")}")),
|
||||
"tooltip_record_screen");
|
||||
|
||||
// 화면 확대
|
||||
mainToolbar.AddStandardButton("화면 확대",
|
||||
"Prefabs/UI/Toolbar/images/ic_menu_zoom_in",
|
||||
new ActionCommand(() => Debug.Log("화면 확대 버튼 클릭됨")),
|
||||
"화면을 한 단계 확대 합니다.");
|
||||
|
||||
//화면 축소
|
||||
mainToolbar.AddStandardButton("화면 축소",
|
||||
"Prefabs/UI/Toolbar/images/ic_menu_zoom_out",
|
||||
new ActionCommand(() => Debug.Log("화면 축소 버튼 클릭됨")),
|
||||
"화면을 한 단계 축소 합니다.");
|
||||
|
||||
// 구분선
|
||||
mainToolbar.AddSeparator();
|
||||
|
||||
// RadioButtonGroup 샘플
|
||||
mainToolbar.AddRadioButton("CameraControlGroup", "Top View", true,
|
||||
"Prefabs/UI/Toolbar/images/ic_camera_top_on",
|
||||
"Prefabs/UI/Toolbar/images/ic_camera_top_off_white",
|
||||
(isSelected) => { if (isSelected) Debug.Log("탑뷰 카메라 선택됨"); },
|
||||
new ActionCommand(() => Debug.Log("탑뷰 카메라 Command 실행")),
|
||||
"Top View 시점으로 변경합니다.");
|
||||
|
||||
mainToolbar.AddRadioButton("CameraControlGroup", "Quarter View", false,
|
||||
"Prefabs/UI/Toolbar/images/ic_camera_quarter_on",
|
||||
"Prefabs/UI/Toolbar/images/ic_camera_quarter_off_white",
|
||||
(isSelected) => { if (isSelected) Debug.Log("쿼터뷰 카메라 선택됨"); },
|
||||
new ActionCommand(() => Debug.Log("쿼터뷰 카메라 Command 실행")),
|
||||
"Quarter View 시점으로 변경합니다.");
|
||||
|
||||
mainToolbar.AddRadioButton("CameraControlGroup", "Front View", false,
|
||||
"Prefabs/UI/Toolbar/images/ic_camera_top_on",
|
||||
"Prefabs/UI/Toolbar/images/ic_camera_top_off_white",
|
||||
@@ -114,66 +151,9 @@ namespace UVC.UI.ToolBar
|
||||
new ActionCommand(() => Debug.Log("프런트뷰 카메라 Command 실행")),
|
||||
"Front View 시점으로 변경합니다.");
|
||||
|
||||
// 예시 2: 구분선 추가
|
||||
mainToolbar.AddSeparator();
|
||||
|
||||
// 예시 3: 표준 버튼 (객체 선택)
|
||||
// AddStandardButton은 텍스트, 아이콘 경로, 클릭 커맨드, 툴팁 키를 파라미터로 받습니다.
|
||||
mainToolbar.AddStandardButton("선택", // 버튼 텍스트 (또는 다국어 키)
|
||||
"Prefabs/UI/Toolbar/images/ic_select_white", // 아이콘 경로
|
||||
new ActionCommand(() => Debug.Log("객체 선택 버튼 클릭됨")), // 클릭 시 실행될 커맨드
|
||||
"객체를 선택합니다."); // 툴팁
|
||||
|
||||
// 객체 이동
|
||||
mainToolbar.AddStandardButton("이동",
|
||||
"Prefabs/UI/Toolbar/images/ic_move_white",
|
||||
new ActionCommand(() => Debug.Log("객체 이동 버튼 클릭됨")),
|
||||
"객체를 이동 시킵니다.");
|
||||
|
||||
// 객체 회전
|
||||
mainToolbar.AddStandardButton("회전",
|
||||
"Prefabs/UI/Toolbar/images/ic_rotation_white",
|
||||
new ActionCommand(() => Debug.Log("객체 회전 버튼 클릭됨")),
|
||||
"객체의 각도를 조절합니다.");
|
||||
|
||||
// 객체 크기조절
|
||||
mainToolbar.AddStandardButton("크기조절",
|
||||
"Prefabs/UI/Toolbar/images/ic_scale_white",
|
||||
new ActionCommand(() => Debug.Log("객체 크기조절 버튼 클릭됨")),
|
||||
"객체 크기를 조절합니다.");
|
||||
|
||||
// 객체 복제
|
||||
mainToolbar.AddStandardButton("복제",
|
||||
"Prefabs/UI/Toolbar/images/ic_copy_white",
|
||||
new ActionCommand(() => Debug.Log("객체 복제 버튼 클릭됨")),
|
||||
"객체를 복제 합니다.");
|
||||
|
||||
// 객체 삭제
|
||||
mainToolbar.AddStandardButton("삭제",
|
||||
"Prefabs/UI/Toolbar/images/ic_delete_white",
|
||||
new ActionCommand(() => Debug.Log("객체 삭제 버튼 클릭됨")),
|
||||
"객체를 삭제 합니다.");
|
||||
|
||||
mainToolbar.AddSeparator();
|
||||
|
||||
// 예시 4: 화면 캡처 버튼 (텍스트가 다국어 키일 수 있음)
|
||||
mainToolbar.AddStandardButton("button_capture_screen", // 다국어 키로 사용될 수 있는 텍스트
|
||||
"Prefabs/UI/Toolbar/images/ic_capture_white",
|
||||
new ActionCommand(() => Debug.Log("화면 캡처 버튼 클릭됨")),
|
||||
"tooltip_capture_screen"); // 툴팁도 다국어 키 사용 가능
|
||||
|
||||
// 예시 5: 화면 녹화 시작/중지 토글 버튼
|
||||
// AddToggleButton은 초기 상태, 선택/해제 아이콘, OnToggle 콜백 등을 설정합니다.
|
||||
// ClickCommand는 ActionCommand<bool>을 사용하여 현재 토글 상태를 파라미터로 받을 수 있습니다.
|
||||
mainToolbar.AddToggleButton("button_record_screen", false, // 초기 상태: 꺼짐(false)
|
||||
"Prefabs/UI/Toolbar/images/ic_record_on_white", // 켜짐(selected) 상태 아이콘
|
||||
"Prefabs/UI/Toolbar/images/ic_record_off_white", // 꺼짐(deselected) 상태 아이콘
|
||||
(isSelected) => Debug.Log($"화면 녹화 상태: {(isSelected ? "녹화 중" : "중지")} (OnToggle 콜백)"),
|
||||
new ActionCommand<bool>((isRecording) => Debug.Log($"화면 녹화 Command 실행: {(isRecording ? "녹화 시작" : "녹화 중지")}")),
|
||||
"tooltip_record_screen");
|
||||
|
||||
|
||||
// 예시 6: 확장 버튼 (브러시 크기 선택)
|
||||
// 예시 : 확장 버튼 (브러시 크기 선택)
|
||||
// AddExpandableButton으로 주 버튼을 만들고, 반환된 객체의 SubButtons 리스트에 하위 버튼들을 추가합니다.
|
||||
var expandableBtnModel = mainToolbar.AddExpandableButton("button_brush_size", // 주 버튼 텍스트/키
|
||||
"Prefabs/UI/Toolbar/images/ic_brush_default_white", // 주 버튼 기본 아이콘
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UVC.UI.Toolbar.Model;
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace UVC.UI.Toolbar.View
|
||||
// 같은 GroupName을 가진 라디오 버튼들은 이 ToggleGroup에 의해 관리됩니다.
|
||||
ToggleGroup uiToggleGroup = viewContext.GetOrCreateToggleGroup(radioModel.GroupName);
|
||||
toggleComponent.group = uiToggleGroup; // UI Toggle을 해당 그룹에 할당
|
||||
|
||||
|
||||
// 모델의 현재 IsSelected 상태로 UI Toggle의 초기 상태를 설정합니다.
|
||||
toggleComponent.SetIsOnWithoutNotify(radioModel.IsSelected);
|
||||
|
||||
|
||||
@@ -5,122 +5,122 @@ using UVC.UI.Toolbar.Model;
|
||||
namespace UVC.UI.Toolbar.View
|
||||
{
|
||||
/// <summary>
|
||||
/// 표준 툴바 버튼(ToolbarStandardButton)의 UI 생성, 이벤트 연결, 시각적 업데이트를 처리하는 클래스입니다.
|
||||
/// IButtonViewProcessor 인터페이스를 구현하여 ToolbarView가 표준 버튼을 일관된 방식으로 다룰 수 있도록 합니다.
|
||||
/// 표준 툴바 버튼(ToolbarStandardButton)의 UI 생성, 이벤트 연결, 시각적 업데이트를 처리하는 클래스입니다.
|
||||
/// IButtonViewProcessor 인터페이스를 구현하여 ToolbarView가 표준 버튼을 일관된 방식으로 다룰 수 있도록 합니다.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 이 클래스의 주요 역할:
|
||||
/// 1. UI 생성: ToolbarView에 설정된 '표준 버튼 프리팹'을 사용하여 버튼의 GameObject를 만듭니다.
|
||||
/// 2. 상호작용 설정: 생성된 버튼 UI(UnityEngine.UI.Button)가 클릭되었을 때,
|
||||
/// 연결된 ToolbarStandardButton 모델의 ExecuteClick 메서드가 호출되도록 설정합니다.
|
||||
/// 3. 시각적 업데이트: 버튼 모델의 상태(텍스트, 아이콘, 활성화 상태 등)가 변경되면,
|
||||
/// 화면에 보이는 버튼의 모습도 그에 맞게 업데이트합니다.
|
||||
/// 이 클래스의 주요 역할:
|
||||
/// 1. UI 생성: ToolbarView에 설정된 '표준 버튼 프리팹'을 사용하여 버튼의 GameObject를 만듭니다.
|
||||
/// 2. 상호작용 설정: 생성된 버튼 UI(UnityEngine.UI.Button)가 클릭되었을 때,
|
||||
/// 연결된 ToolbarStandardButton 모델의 ExecuteClick 메서드가 호출되도록 설정합니다.
|
||||
/// 3. 시각적 업데이트: 버튼 모델의 상태(텍스트, 아이콘, 활성화 상태 등)가 변경되면,
|
||||
/// 화면에 보이는 버튼의 모습도 그에 맞게 업데이트합니다.
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // ToolbarView 내에서 이 프로세서가 사용되는 방식 (간략화된 예시):
|
||||
/// // 1. ToolbarModel로부터 ToolbarStandardButton 객체를 가져옵니다.
|
||||
/// // ToolbarView 내에서 이 프로세서가 사용되는 방식 (간략화된 예시):
|
||||
/// // 1. ToolbarModel로부터 ToolbarStandardButton 객체를 가져옵니다.
|
||||
/// // ToolbarStandardButton standardButtonModel = new ToolbarStandardButton { Text = "Save", ... };
|
||||
///
|
||||
/// // 2. ToolbarView는 해당 모델 타입에 맞는 Processor를 찾습니다.
|
||||
/// // 2. ToolbarView는 해당 모델 타입에 맞는 Processor를 찾습니다.
|
||||
/// // IButtonViewProcessor processor = GetButtonViewProcessor(typeof(ToolbarStandardButton));
|
||||
/// // (이때, ToolbarStandardButtonViewProcessor 인스턴스가 반환됩니다)
|
||||
/// // (이때, ToolbarStandardButtonViewProcessor 인스턴스가 반환됩니다)
|
||||
///
|
||||
/// // 3. UI 생성 요청
|
||||
/// // 3. UI 생성 요청
|
||||
/// // GameObject buttonUI = processor.CreateButtonUI(standardButtonModel, toolbarContainer, this);
|
||||
///
|
||||
/// // 4. 상호작용 및 초기 시각적 요소 설정 요청
|
||||
/// // 4. 상호작용 및 초기 시각적 요소 설정 요청
|
||||
/// // processor.SetupButtonInteractions(standardButtonModel, buttonUI, this);
|
||||
///
|
||||
/// // 5. 모델의 상태가 변경되면(예: standardButtonModel.Text = "Save As";) OnStateChanged 이벤트가 발생하고,
|
||||
/// // ToolbarView는 다시 processor.UpdateCommonButtonVisuals()를 호출하여 UI를 업데이트합니다.
|
||||
/// // 5. 모델의 상태가 변경되면(예: standardButtonModel.Text = "Save As";) OnStateChanged 이벤트가 발생하고,
|
||||
/// // ToolbarView는 다시 processor.UpdateCommonButtonVisuals()를 호출하여 UI를 업데이트합니다.
|
||||
/// // standardButtonModel.OnStateChanged += () => processor.UpdateCommonButtonVisuals(standardButtonModel, buttonUI, this);
|
||||
/// </code>
|
||||
/// </example>
|
||||
public class ToolbarStandardButtonViewProcessor : IButtonViewProcessor
|
||||
{
|
||||
/// <summary>
|
||||
/// ToolbarStandardButton 모델에 해당하는 UI GameObject를 생성합니다.
|
||||
/// ToolbarView에 있는 standardButtonPrefab을 복제하여 사용합니다.
|
||||
/// ToolbarStandardButton 모델에 해당하는 UI GameObject를 생성합니다.
|
||||
/// ToolbarView에 있는 standardButtonPrefab을 복제하여 사용합니다.
|
||||
/// </summary>
|
||||
/// <param name="buttonModel">UI를 생성할 기반이 되는 버튼 데이터 모델 (ToolbarButtonBase 타입이지만, 실제로는 ToolbarStandardButton으로 간주됨).</param>
|
||||
/// <param name="parentContainer">생성된 버튼 UI가 자식으로 추가될 부모 Transform 객체입니다.</param>
|
||||
/// <param name="viewContext">현재 ToolbarView의 인스턴스. 프리팹 참조나 다른 뷰 관련 기능에 접근할 때 사용됩니다.</param>
|
||||
/// <returns>성공적으로 생성된 버튼의 GameObject. 프리팹이 없으면 null을 반환합니다.</returns>
|
||||
/// <param name="buttonModel">UI를 생성할 기반이 되는 버튼 데이터 모델 (ToolbarButtonBase 타입이지만, 실제로는 ToolbarStandardButton으로 간주됨).</param>
|
||||
/// <param name="parentContainer">생성된 버튼 UI가 자식으로 추가될 부모 Transform 객체입니다.</param>
|
||||
/// <param name="viewContext">현재 ToolbarView의 인스턴스. 프리팹 참조나 다른 뷰 관련 기능에 접근할 때 사용됩니다.</param>
|
||||
/// <returns>성공적으로 생성된 버튼의 GameObject. 프리팹이 없으면 null을 반환합니다.</returns>
|
||||
public GameObject CreateButtonUI(ToolbarButtonBase buttonModel, Transform parentContainer, ToolbarView viewContext)
|
||||
{
|
||||
if (viewContext.standardButtonPrefab == null)
|
||||
{
|
||||
Debug.LogError("StandardButtonViewProcessor: standardButtonPrefab이 ToolbarView에 할당되지 않았습니다.", viewContext);
|
||||
Debug.LogError("StandardButtonViewProcessor: standardButtonPrefab이 ToolbarView에 할당되지 않았습니다.", viewContext);
|
||||
return null;
|
||||
}
|
||||
// standardButtonPrefab을 복제하여 새로운 버튼 UI GameObject를 만듭니다.
|
||||
// parentContainer의 자식으로 생성되어 툴바 레이아웃에 포함됩니다.
|
||||
// standardButtonPrefab을 복제하여 새로운 버튼 UI GameObject를 만듭니다.
|
||||
// parentContainer의 자식으로 생성되어 툴바 레이아웃에 포함됩니다.
|
||||
return Object.Instantiate(viewContext.standardButtonPrefab, parentContainer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 생성된 표준 버튼 UI GameObject에 필요한 상호작용을 설정하고 초기 시각적 상태를 업데이트합니다.
|
||||
/// - UI 버튼 클릭 시 모델의 ExecuteClick 메서드 호출 설정
|
||||
/// - 모델의 초기 텍스트, 아이콘, 활성화 상태를 UI에 반영
|
||||
/// 생성된 표준 버튼 UI GameObject에 필요한 상호작용을 설정하고 초기 시각적 상태를 업데이트합니다.
|
||||
/// - UI 버튼 클릭 시 모델의 ExecuteClick 메서드 호출 설정
|
||||
/// - 모델의 초기 텍스트, 아이콘, 활성화 상태를 UI에 반영
|
||||
/// </summary>
|
||||
/// <param name="buttonModel">설정 대상 버튼의 데이터 모델 (ToolbarStandardButton으로 캐스팅하여 사용).</param>
|
||||
/// <param name="buttonUIObject">화면에 표시된, 설정할 버튼의 UI GameObject.</param>
|
||||
/// <param name="viewContext">현재 ToolbarView의 인스턴스.</param>
|
||||
/// <param name="buttonModel">설정 대상 버튼의 데이터 모델 (ToolbarStandardButton으로 캐스팅하여 사용).</param>
|
||||
/// <param name="buttonUIObject">화면에 표시된, 설정할 버튼의 UI GameObject.</param>
|
||||
/// <param name="viewContext">현재 ToolbarView의 인스턴스.</param>
|
||||
public void SetupButtonInteractions(ToolbarButtonBase buttonModel, GameObject buttonUIObject, ToolbarView viewContext)
|
||||
{
|
||||
// buttonModel을 실제 타입인 ToolbarStandardButton으로 변환합니다.
|
||||
// buttonModel을 실제 타입인 ToolbarStandardButton으로 변환합니다.
|
||||
ToolbarStandardButton standardModel = buttonModel as ToolbarStandardButton;
|
||||
if (standardModel == null) return;
|
||||
|
||||
// 버튼 UI GameObject에서 UnityEngine.UI.Button 컴포넌트를 가져옵니다.
|
||||
// 버튼 UI GameObject에서 UnityEngine.UI.Button 컴포넌트를 가져옵니다.
|
||||
Button uiButton = buttonUIObject.GetComponent<Button>();
|
||||
if (uiButton != null)
|
||||
{
|
||||
// 버튼 클릭 이벤트에 리스너(실행할 함수)를 추가합니다.
|
||||
// 버튼이 클릭되면 standardModel의 ExecuteClick 메서드가 호출됩니다.
|
||||
// standardModel.Text를 파라미터로 전달하는 것은 예시이며, 필요에 따라 null이나 다른 값을 전달할 수 있습니다.
|
||||
// 버튼 클릭 이벤트에 리스너(실행할 함수)를 추가합니다.
|
||||
// 버튼이 클릭되면 standardModel의 ExecuteClick 메서드가 호출됩니다.
|
||||
// standardModel.Text를 파라미터로 전달하는 것은 예시이며, 필요에 따라 null이나 다른 값을 전달할 수 있습니다.
|
||||
uiButton.onClick.AddListener(() =>
|
||||
{
|
||||
standardModel.ExecuteClick(standardModel.Text); // 모델의 클릭 로직 실행
|
||||
standardModel.ExecuteClick(standardModel.Text); // 모델의 클릭 로직 실행
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"StandardButtonViewProcessor: StandardButton '{standardModel.Text}'의 GameObject에 Button 컴포넌트가 없습니다.", buttonUIObject);
|
||||
Debug.LogError($"StandardButtonViewProcessor: StandardButton '{standardModel.Text}'의 GameObject에 Button 컴포넌트가 없습니다.", buttonUIObject);
|
||||
}
|
||||
|
||||
// 버튼의 초기 시각적 상태(텍스트, 아이콘, 활성화 상태 등)를 설정합니다.
|
||||
// 버튼의 초기 시각적 상태(텍스트, 아이콘, 활성화 상태 등)를 설정합니다.
|
||||
UpdateCommonButtonVisuals(buttonModel, buttonUIObject, viewContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 버튼 모델의 공통적인 시각적 속성(텍스트, 아이콘, 활성화 상태)이 변경되었을 때 UI를 업데이트합니다.
|
||||
/// 실제 업데이트 로직은 ToolbarView의 InternalUpdateCommonButtonVisuals 메서드에 위임합니다.
|
||||
/// 버튼 모델의 공통적인 시각적 속성(텍스트, 아이콘, 활성화 상태)이 변경되었을 때 UI를 업데이트합니다.
|
||||
/// 실제 업데이트 로직은 ToolbarView의 InternalUpdateCommonButtonVisuals 메서드에 위임합니다.
|
||||
/// </summary>
|
||||
/// <param name="buttonModel">상태가 변경된 버튼의 데이터 모델.</param>
|
||||
/// <param name="buttonUIObject">업데이트할 UI GameObject.</param>
|
||||
/// <param name="viewContext">현재 ToolbarView의 인스턴스.</param>
|
||||
/// <param name="buttonModel">상태가 변경된 버튼의 데이터 모델.</param>
|
||||
/// <param name="buttonUIObject">업데이트할 UI GameObject.</param>
|
||||
/// <param name="viewContext">현재 ToolbarView의 인스턴스.</param>
|
||||
public void UpdateCommonButtonVisuals(ToolbarButtonBase buttonModel, GameObject buttonUIObject, ToolbarView viewContext)
|
||||
{
|
||||
// ToolbarView에 있는 공통 UI 업데이트 로직을 호출합니다.
|
||||
// 이 메서드는 버튼의 텍스트, 아이콘, 활성화(interactable) 상태 등을 모델에 맞춰 업데이트합니다.
|
||||
// ToolbarView에 있는 공통 UI 업데이트 로직을 호출합니다.
|
||||
// 이 메서드는 버튼의 텍스트, 아이콘, 활성화(interactable) 상태 등을 모델에 맞춰 업데이트합니다.
|
||||
viewContext.InternalUpdateCommonButtonVisuals(buttonModel, buttonUIObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 표준 버튼은 토글 상태(선택됨/해제됨)를 가지지 않으므로, 이 메서드는 아무 작업도 수행하지 않습니다.
|
||||
/// IButtonViewProcessor 인터페이스를 구현하기 위해 필요합니다.
|
||||
/// 표준 버튼은 토글 상태(선택됨/해제됨)를 가지지 않으므로, 이 메서드는 아무 작업도 수행하지 않습니다.
|
||||
/// IButtonViewProcessor 인터페이스를 구현하기 위해 필요합니다.
|
||||
/// </summary>
|
||||
/// <param name="toggleButtonModel">토글 버튼 모델 (여기서는 사용되지 않음).</param>
|
||||
/// <param name="buttonUIObject">UI GameObject (여기서는 사용되지 않음).</param>
|
||||
/// <param name="isSelected">선택 상태 (여기서는 사용되지 않음).</param>
|
||||
/// <param name="viewContext">ToolbarView 컨텍스트 (여기서는 사용되지 않음).</param>
|
||||
/// <param name="toggleButtonModel">토글 버튼 모델 (여기서는 사용되지 않음).</param>
|
||||
/// <param name="buttonUIObject">UI GameObject (여기서는 사용되지 않음).</param>
|
||||
/// <param name="isSelected">선택 상태 (여기서는 사용되지 않음).</param>
|
||||
/// <param name="viewContext">ToolbarView 컨텍스트 (여기서는 사용되지 않음).</param>
|
||||
public void UpdateToggleStateVisuals(ToolbarToggleButton toggleButtonModel, GameObject buttonUIObject, bool isSelected, ToolbarView viewContext)
|
||||
{
|
||||
// 표준 버튼은 별도의 '토글 선택 상태'에 따른 시각적 변화가 없습니다.
|
||||
// 예를 들어, 배경색이 바뀌거나 체크마크가 표시되는 등의 변화가 없습니다.
|
||||
// 따라서 이 메서드는 비워둡니다.
|
||||
// 표준 버튼은 별도의 '토글 선택 상태'에 따른 시각적 변화가 없습니다.
|
||||
// 예를 들어, 배경색이 바뀌거나 체크마크가 표시되는 등의 변화가 없습니다.
|
||||
// 따라서 이 메서드는 비워둡니다.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#nullable enable
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
@@ -85,9 +85,9 @@ namespace UVC.UI.Toolbar.View
|
||||
[Header("UI Prefabs")]
|
||||
[Tooltip("표준 버튼 UI에 사용될 프리팹입니다.")]
|
||||
public GameObject standardButtonPrefab;
|
||||
[Tooltip("토글 버튼 UI에 사용될 프리팹입니다.")]
|
||||
[Tooltip("토글 버튼 UI에 사용될 프리팹입니다. IsOn=false로 설정해 놔야 합니다.")]
|
||||
public GameObject toggleButtonPrefab;
|
||||
[Tooltip("라디오 버튼 UI에 사용될 프리팹입니다.")]
|
||||
[Tooltip("라디오 버튼 UI에 사용될 프리팹입니다. IsOn=false로 설정해 놔야 합니다.")]
|
||||
public GameObject radioButtonPrefab;
|
||||
[Tooltip("확장 가능한 버튼 UI에 사용될 프리팹입니다.")]
|
||||
public GameObject expandableButtonPrefab;
|
||||
@@ -113,7 +113,7 @@ namespace UVC.UI.Toolbar.View
|
||||
/// 각 버튼 타입(표준, 토글 등)에 맞는 IButtonViewProcessor 구현체를 등록하여 사용합니다.
|
||||
/// </summary>
|
||||
private Dictionary<System.Type, IButtonViewProcessor> _buttonViewProcessors = new Dictionary<System.Type, IButtonViewProcessor>();
|
||||
|
||||
|
||||
|
||||
// --- 헬퍼 클래스 ---
|
||||
private ToggleGroupManager _toggleGroupManager;
|
||||
@@ -147,7 +147,7 @@ namespace UVC.UI.Toolbar.View
|
||||
|
||||
// UI 컨테이너와 레이아웃 그룹을 자동으로 찾거나 설정합니다.
|
||||
if (toolbarContainer == null) toolbarContainer = GetComponent<Transform>();
|
||||
if (toolbarContainer == null) toolbarContainer = GetComponentInChildren<Transform>(true);
|
||||
if (toolbarContainer == null) toolbarContainer = GetComponentInChildren<Transform>(true);
|
||||
if (toolbarContainer == null) Debug.LogError("ToolbarView: toolbarContainer가 할당되지 않았습니다.", this);
|
||||
|
||||
if (layoutGroup == null && toolbarContainer != null)
|
||||
@@ -225,7 +225,7 @@ namespace UVC.UI.Toolbar.View
|
||||
pair.Key.ClearEventHandlers();
|
||||
}
|
||||
if (pair.Value != null)
|
||||
{
|
||||
{
|
||||
// UI 컴포넌트의 이벤트 리스너를 명시적으로 해제합니다.
|
||||
Toggle toggleComponent = pair.Value.GetComponent<Toggle>();
|
||||
if (toggleComponent != null) toggleComponent.onValueChanged.RemoveAllListeners();
|
||||
@@ -288,7 +288,7 @@ namespace UVC.UI.Toolbar.View
|
||||
// 모델의 각 아이템을 순회하며 UI를 생성합니다.
|
||||
foreach (var itemModel in ToolbarModel.Items)
|
||||
{
|
||||
GameObject itemUIObject = null;
|
||||
GameObject? itemUIObject = null;
|
||||
|
||||
if (itemModel is ToolbarSeparator)
|
||||
{
|
||||
@@ -297,7 +297,7 @@ namespace UVC.UI.Toolbar.View
|
||||
else Debug.LogError("ToolbarView: separatorPrefab이 할당되지 않았습니다.", this);
|
||||
}
|
||||
else if (itemModel is ToolbarButtonBase buttonModel)
|
||||
{
|
||||
{
|
||||
// 버튼 모델인 경우
|
||||
IButtonViewProcessor processor = GetButtonViewProcessor(buttonModel.GetType());
|
||||
if (processor != null)
|
||||
@@ -383,8 +383,8 @@ namespace UVC.UI.Toolbar.View
|
||||
Image iconImageComponent = itemObj.transform.Find("Icon")?.GetComponent<Image>() ?? itemObj.GetComponentInChildren<Image>(true);
|
||||
if (iconImageComponent != null)
|
||||
{
|
||||
string iconPathToLoad = (model is ToolbarToggleButton toggleButton && !toggleButton.IsSelected)
|
||||
? toggleButton.OffIconSpritePath
|
||||
string iconPathToLoad = (model is ToolbarToggleButton toggleButton && !toggleButton.IsSelected)
|
||||
? toggleButton.OffIconSpritePath
|
||||
: model.IconSpritePath;
|
||||
|
||||
if (!string.IsNullOrEmpty(iconPathToLoad))
|
||||
@@ -432,7 +432,7 @@ namespace UVC.UI.Toolbar.View
|
||||
protected Sprite LoadSpriteFromResources(string spritePath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(spritePath)) return null;
|
||||
|
||||
|
||||
Sprite loadedSprite = Resources.Load<Sprite>(spritePath);
|
||||
if (loadedSprite == null)
|
||||
{
|
||||
@@ -455,7 +455,7 @@ namespace UVC.UI.Toolbar.View
|
||||
/// 툴바 UI를 정리(ClearToolbar)하여 메모리 누수를 방지합니다.
|
||||
/// </summary>
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
{
|
||||
ClearToolbar();
|
||||
|
||||
if (TooltipManager.Instance != null && TooltipManager.Instance.IsInitialized)
|
||||
|
||||
69
Assets/Scripts/UVC/Util/AlarmBadge.cs
Normal file
69
Assets/Scripts/UVC/Util/AlarmBadge.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UVC.Factory.Util
|
||||
{
|
||||
public class AlarmBadge : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private RectTransform badgeRectTransform;
|
||||
[SerializeField]
|
||||
private TextMeshProUGUI badgeText;
|
||||
[SerializeField]
|
||||
private int margin = 10;
|
||||
[SerializeField]
|
||||
private int badgeCount = 0;
|
||||
public int BadgeCount
|
||||
{
|
||||
get => badgeCount;
|
||||
set
|
||||
{
|
||||
if (badgeCount == value || value < 0) return;
|
||||
badgeCount = value;
|
||||
SetBadgeCount(badgeCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (badgeRectTransform == null)
|
||||
{
|
||||
badgeRectTransform = GetComponent<RectTransform>();
|
||||
}
|
||||
if (badgeText == null)
|
||||
{
|
||||
badgeText = GetComponentInChildren<TextMeshProUGUI>();
|
||||
}
|
||||
SetBadgeCount(badgeCount);
|
||||
}
|
||||
|
||||
private void SetBadgeCount(int count)
|
||||
{
|
||||
if (count <= 0)
|
||||
{
|
||||
badgeRectTransform.gameObject.SetActive(false);
|
||||
return;
|
||||
}
|
||||
badgeText.text = count.ToString();
|
||||
badgeRectTransform.gameObject.SetActive(true);
|
||||
// 숫자 크기에 따라 badgeText 크기 조정
|
||||
if (count > 999)
|
||||
{
|
||||
badgeText.text = "999+";
|
||||
}
|
||||
else
|
||||
{
|
||||
badgeText.text = count.ToString();
|
||||
}
|
||||
// badgeText 글자 크기에 따라 rectTransform 넓이 조절하고 Image는 badgeText 넓이 +margin 하는 코드
|
||||
var sizeDelta = badgeRectTransform.sizeDelta;
|
||||
sizeDelta.x = badgeText.preferredWidth + margin;
|
||||
if(sizeDelta.x < badgeRectTransform.sizeDelta.y)
|
||||
{
|
||||
sizeDelta.x = badgeRectTransform.sizeDelta.y; // Ensure width is at least equal to height
|
||||
}
|
||||
badgeRectTransform.sizeDelta = sizeDelta;
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/UVC/Util/AlarmBadge.cs.meta
Normal file
2
Assets/Scripts/UVC/Util/AlarmBadge.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e885581aa4c7da4495c05983f25356a
|
||||
@@ -25,7 +25,7 @@ namespace UVC.UI.Util
|
||||
[SerializeField]
|
||||
private Image targetImage; // 컬러를 변경할 이미지 컴포넌트
|
||||
[SerializeField]
|
||||
private Button button; // 버튼 컴포넌트
|
||||
private Selectable button; // 버튼 컴포넌트
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
@@ -36,20 +36,52 @@ namespace UVC.UI.Util
|
||||
if (targetImage != null)
|
||||
{
|
||||
targetImage.color = originalColor; // 초기 컬러 설정
|
||||
targetImage.color = enabled ? originalColor : disabledColor;
|
||||
}
|
||||
if (button == null)
|
||||
{
|
||||
button = GetComponent<Button>();
|
||||
}
|
||||
if(button != null)
|
||||
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (button != null)
|
||||
{
|
||||
button.transition = Selectable.Transition.None; // 버튼의 전환 효과를 비활성화
|
||||
|
||||
Color color = button.enabled && button.interactable ? originalColor : disabledColor;
|
||||
if (button is Toggle toggle)
|
||||
{
|
||||
color = toggle.isOn ? clickColor : originalColor; // 토글 상태에 따라 컬러 변경
|
||||
|
||||
toggle.onValueChanged.AddListener(onValueChangedToggle);
|
||||
}
|
||||
|
||||
if (targetImage != null) targetImage.color = color;
|
||||
}
|
||||
}
|
||||
|
||||
private void onValueChangedToggle(bool isOn)
|
||||
{
|
||||
if (targetImage != null)
|
||||
{
|
||||
targetImage.color = isOn ? clickColor : originalColor; // 토글 상태에 따라 컬러 변경
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (button != null && button is Toggle toggle)
|
||||
{
|
||||
toggle.onValueChanged.RemoveListener(onValueChangedToggle);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
if (button.interactable)
|
||||
if ((button != null && button.interactable) || (button == null && enabled))
|
||||
{
|
||||
if (targetImage != null)
|
||||
{
|
||||
@@ -67,7 +99,7 @@ namespace UVC.UI.Util
|
||||
|
||||
public void OnPointerEnter(PointerEventData eventData)
|
||||
{
|
||||
if (button.interactable)
|
||||
if ((button != null && button.interactable) || (button == null && enabled))
|
||||
{
|
||||
if (targetImage != null)
|
||||
{
|
||||
@@ -78,11 +110,19 @@ namespace UVC.UI.Util
|
||||
|
||||
public void OnPointerExit(PointerEventData eventData)
|
||||
{
|
||||
if (button.interactable)
|
||||
if ((button != null && button.interactable) || (button == null && enabled))
|
||||
{
|
||||
if (targetImage != null)
|
||||
if (button != null && button is Toggle toggle)
|
||||
{
|
||||
targetImage.color = originalColor; // 마우스가 벗어날 때 원래 컬러로 변경
|
||||
if (targetImage != null)
|
||||
targetImage.color = toggle.isOn ? clickColor : originalColor; // 토글 상태에 따라 컬러 변경
|
||||
}
|
||||
else
|
||||
{
|
||||
if (targetImage != null)
|
||||
{
|
||||
targetImage.color = originalColor; // 마우스가 벗어날 때 원래 컬러로 변경
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -96,11 +136,11 @@ namespace UVC.UI.Util
|
||||
|
||||
public void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
if (button.interactable)
|
||||
if ((button != null && button.interactable) || (button == null && enabled))
|
||||
{
|
||||
if (targetImage != null)
|
||||
{
|
||||
targetImage.color = originalColor; // 클릭 후 원래 컬러로 변경
|
||||
targetImage.color = hoverColor; // 클릭 후 원래 컬러로 변경
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4185643eda515744385d49b83fe88dce
|
||||
guid: 75536bd8c4a0290479506cdfb3d001b2
|
||||
Reference in New Issue
Block a user