using System.Collections.Generic; using System.Linq; namespace UVC.UI.Toolbar.Model { /// /// 여러 개의 ToolbarRadioButton 객체들을 하나의 그룹으로 관리합니다. /// 이 그룹 내에서는 오직 하나의 라디오 버튼만이 선택된(IsSelected = true) 상태를 가질 수 있도록 보장합니다. /// /// /// ToolbarModel은 ToolbarRadioButton이 추가될 때 GroupName을 기준으로 이 클래스의 인스턴스를 생성하거나 /// 기존 인스턴스를 찾아 라디오 버튼을 등록(RegisterButton)합니다. /// 사용자가 라디오 버튼을 클릭하면, 해당 버튼은 이 그룹의 SetSelected 메서드를 호출하여 /// 자신을 선택 상태로 만들고 그룹 내 다른 버튼들은 선택 해제 상태로 변경합니다. /// /// /// /// // 이 클래스는 주로 ToolbarModel 내부에서 사용됩니다. 개발자가 직접 생성하기보다는 /// // ToolbarModel에 ToolbarRadioButton을 추가함으로써 간접적으로 사용됩니다. /// /// // ToolbarModel 내부에서의 사용 흐름 (간략화된 예시) /// // public class ToolbarModel /// // { /// // private Dictionary _radioGroups = new Dictionary(); /// // /// // public void AddItem(IToolbarItem item) /// // { /// // if (item is ToolbarRadioButton radioButton) /// // { /// // if (!_radioGroups.TryGetValue(radioButton.GroupName, out var group)) /// // { /// // group = new ToolbarRadioButtonGroup(); /// // _radioGroups.Add(radioButton.GroupName, group); /// // } /// // group.RegisterButton(radioButton); // 라디오 버튼을 그룹에 등록 /// // radioButton.RadioGroup = group; // 버튼에 그룹 참조 설정 /// // } /// // // ... /// // } /// // } /// /// // 그룹 내 버튼 선택 로직 (ToolbarRadioButton의 ExecuteClick 내부에서 호출됨) /// // ToolbarRadioButtonGroup cameraGroup = new ToolbarRadioButtonGroup(); /// // ToolbarRadioButton radio1 = new ToolbarRadioButton("camera") { Text = "Cam1" }; /// // ToolbarRadioButton radio2 = new ToolbarRadioButton("camera") { Text = "Cam2" }; /// // /// // cameraGroup.RegisterButton(radio1); /// // cameraGroup.RegisterButton(radio2); /// // radio1.RadioGroup = cameraGroup; /// // radio2.RadioGroup = cameraGroup; /// // /// // // radio1을 선택 (radio1.IsSelected = true, radio2.IsSelected = false가 됨) /// // cameraGroup.SetSelected(radio1); /// // UnityEngine.Debug.Log($"Radio1 Selected: {radio1.IsSelected}, Radio2 Selected: {radio2.IsSelected}"); /// // /// // // radio2를 선택 (radio1.IsSelected = false, radio2.IsSelected = true가 됨) /// // cameraGroup.SetSelected(radio2); /// // UnityEngine.Debug.Log($"Radio1 Selected: {radio1.IsSelected}, Radio2 Selected: {radio2.IsSelected}"); /// /// public class ToolbarRadioButtonGroup { private List _buttons = new List(); /// /// 현재 그룹 내에서 선택된 라디오 버튼입니다. /// 선택된 버튼이 없으면 null을 반환할 수 있습니다 (일반적으로 그룹은 항상 하나가 선택되도록 설계되지만, 초기 상태 등 예외 가능). /// public ToolbarRadioButton SelectedButton { get; private set; } /// /// 지정된 라디오 버튼을 이 그룹에 등록합니다. /// 등록된 버튼은 그룹의 선택 관리 대상이 됩니다. /// 버튼의 RadioGroup 속성에도 이 그룹의 참조가 설정되어야 합니다 (보통 ToolbarModel에서 처리). /// /// 그룹에 등록할 ToolbarRadioButton입니다. public void RegisterButton(ToolbarRadioButton button) { if (!_buttons.Contains(button)) { _buttons.Add(button); } } /// /// 지정된 라디오 버튼을 그룹 내에서 선택된 상태로 설정합니다. /// 이전에 선택되었던 다른 버튼은 선택 해제 상태(IsSelected = false)로 변경됩니다. /// /// 선택할 ToolbarRadioButton입니다. 이 버튼은 반드시 그룹에 미리 등록되어 있어야 합니다. public void SetSelected(ToolbarRadioButton buttonToSelect) { if (buttonToSelect == null || !_buttons.Contains(buttonToSelect)) { // 그룹에 등록되지 않은 버튼을 선택하려고 하면 무시하거나 경고를 로깅할 수 있습니다. UnityEngine.Debug.LogWarning($"SetSelected: 버튼 '{buttonToSelect?.Text}' (그룹: {buttonToSelect?.GroupName})은 현재 라디오 그룹에 등록되어 있지 않습니다."); return; } // 이미 선택된 버튼을 다시 클릭한 경우, 상태를 변경하지 않고 유지합니다. // (라디오 버튼은 일반적으로 한 번 선택되면 사용자가 직접 해제할 수 없고, 다른 버튼을 선택해야 해제됨) if (SelectedButton == buttonToSelect && buttonToSelect.IsSelected) { return; } SelectedButton = buttonToSelect; // 새 버튼을 선택된 버튼으로 설정 foreach (var buttonInGroup in _buttons) { // 현재 순회 중인 버튼이 선택하려는 버튼(buttonToSelect)과 동일한지 비교하여 // IsSelected 상태를 설정합니다. // 이렇게 하면 buttonToSelect만 true가 되고 나머지는 false가 됩니다. // IsSelected 속성의 setter는 필요한 이벤트(OnToggle, OnStateChanged 등)를 발생시킵니다. buttonInGroup.IsSelected = (buttonInGroup == buttonToSelect); } } /// /// 그룹에 등록된 모든 라디오 버튼의 목록을 가져옵니다. /// /// 그룹 내 모든 ToolbarRadioButton의 읽기 전용 컬렉션입니다. public IReadOnlyList GetButtons() { return _buttons.AsReadOnly(); } /// /// 그룹 내 버튼들의 초기 선택 상태를 설정합니다. /// 주로 ToolbarModel에서 라디오 버튼들을 추가한 후 호출될 수 있습니다. /// initialState가 true인 버튼이 있다면 해당 버튼을, 없다면 첫 번째 버튼을 선택합니다. /// internal void InitializeSelection() { if (!_buttons.Any()) return; ToolbarRadioButton buttonToSelectInitially = _buttons.FirstOrDefault(b => b.IsSelected); if (buttonToSelectInitially != null) { // initialState가 true로 설정된 버튼이 있다면, 해당 버튼으로 최종 선택 상태를 확정합니다. // (다른 initialState=true 버튼이 실수로 여러 개 있었을 경우를 대비하여 명확히 하나만 선택되도록 함) SetSelected(buttonToSelectInitially); } else { // IsSelected가 true인 버튼이 하나도 없다면, 그룹의 첫 번째 버튼을 기본으로 선택합니다. // (라디오 그룹은 일반적으로 항상 하나가 선택되어 있는 상태를 유지하려 함) SetSelected(_buttons[0]); } } } }