diff --git a/Assets/ControlPanel.cs b/Assets/ControlPanel.cs index 8c6a7ec..fc528db 100644 --- a/Assets/ControlPanel.cs +++ b/Assets/ControlPanel.cs @@ -5,38 +5,47 @@ using UnityEngine.UI; public class ControlPanel : MonoBehaviour { [Header("Core UI (assign in Inspector)")] - public TMP_InputField inputField; // was DegreesInputField - public TMP_Dropdown directionDropdown; // was DirectionDropdown - public Button button; // was RotateButton + public TMP_InputField inputField; + public TMP_Dropdown directionDropdown; + public Button button; // existing Send/Rotate button in hierarchy - private enum Mode { None, DC, Display } + private enum Mode { None, DC, Display, Speaker } private Mode _mode = Mode.None; private DCMotorModule _dc; private DisplayModule _display; + private SpeakerModule _speaker; - // Keep separate inputs so they don't interfere private string _savedDCInput = ""; private int _savedDirectionIndex = 0; private string _savedDisplayInput = ""; - // Found automatically (no new UI objects) - private TextMeshProUGUI _caption; // DegreesCaption text - private TextMeshProUGUI _buttonText; // RotateButton/Text (TMP) - private GameObject _directionCaptionGO; // DirectionCaption - private GameObject _directionDropdownGO; // DirectionDropdown GameObject + // Found automatically (no hierarchy edits) + private TextMeshProUGUI _caption; // child "DegreesCaption" + private TextMeshProUGUI _buttonText; // child "RotateButton/Text (TMP)" + private GameObject _directionCaptionGO; + private GameObject _directionDropdownGO; + + // Created in code (Speaker mode only) + private Button _uploadButton; + private TextMeshProUGUI _uploadButtonText; + private Button _playButton; + private TextMeshProUGUI _playButtonText; private void Awake() { CacheUIFromHierarchy(); + // Create these once; hide unless Speaker mode + CreateUploadButtonIfNeeded(); + CreatePlayButtonIfNeeded(); + if (button != null) { button.onClick.RemoveAllListeners(); - button.onClick.AddListener(OnButtonClicked); + button.onClick.AddListener(OnMainButtonClicked); } - // Cache typed values so switching modules restores what you typed if (inputField != null) { inputField.onValueChanged.AddListener(_ => CacheCurrentInput()); @@ -52,29 +61,17 @@ public class ControlPanel : MonoBehaviour } } - /// - /// Call this whenever a DC or Display module is selected. - /// public void Initialize(ModuleBase module) { CacheCurrentInput(); _dc = module as DCMotorModule; _display = module as DisplayModule; + _speaker = module as SpeakerModule; - if (_dc != null) - { - SwitchMode(Mode.DC); - gameObject.SetActive(true); - return; - } - - if (_display != null) - { - SwitchMode(Mode.Display); - gameObject.SetActive(true); - return; - } + if (_dc != null) { SwitchMode(Mode.DC); gameObject.SetActive(true); return; } + if (_display != null) { SwitchMode(Mode.Display); gameObject.SetActive(true); return; } + if (_speaker != null) { SwitchMode(Mode.Speaker); gameObject.SetActive(true); return; } HidePanel(); } @@ -86,11 +83,13 @@ public class ControlPanel : MonoBehaviour _mode = Mode.None; _dc = null; _display = null; + _speaker = null; + SetUploadVisible(false); + SetPlayVisible(false); } private void CacheUIFromHierarchy() { - // Assumes this script is on the parent that contains these children var captionT = transform.Find("DegreesCaption"); if (captionT != null) _caption = captionT.GetComponent(); @@ -111,30 +110,64 @@ public class ControlPanel : MonoBehaviour if (_mode == Mode.DC) { - if (_caption != null) _caption.text = "Degrees"; - if (_buttonText != null) _buttonText.text = "Rotate"; + SetCaption("Degrees"); + SetCaptionVisible(true); + SetMainButtonText("Rotate"); SetDirectionVisible(true); + SetInputVisible(true); + SetUploadVisible(false); + SetPlayVisible(false); if (inputField != null) + { + inputField.readOnly = false; inputField.SetTextWithoutNotify(_savedDCInput); + } if (directionDropdown != null) directionDropdown.SetValueWithoutNotify(_savedDirectionIndex); } else if (_mode == Mode.Display) { - if (_caption != null) _caption.text = "Text"; - if (_buttonText != null) _buttonText.text = "Send"; + SetCaption("Text"); + SetCaptionVisible(true); + SetMainButtonText("Send"); SetDirectionVisible(false); - - // Prefer module's current displayText; fallback to last typed text - string toShow = _savedDisplayInput; - if (_display != null && !string.IsNullOrEmpty(_display.displayText)) - toShow = _display.displayText; + SetInputVisible(true); + SetUploadVisible(false); + SetPlayVisible(false); if (inputField != null) + { + inputField.readOnly = false; + string toShow = _savedDisplayInput; + if (_display != null && !string.IsNullOrEmpty(_display.displayText)) + toShow = _display.displayText; inputField.SetTextWithoutNotify(toShow); + } } + else if (_mode == Mode.Speaker) + { + // Speaker UI: no input field (removes the white box behind buttons) + SetMainButtonText("Send Audio"); + SetCaptionVisible(false); + SetDirectionVisible(false); + SetInputVisible(false); + + // Show speaker buttons + SetUploadVisible(true); + SetPlayVisible(true); + } + } + + private void SetCaption(string text) + { + if (_caption != null) _caption.text = text; + } + + private void SetMainButtonText(string text) + { + if (_buttonText != null) _buttonText.text = text; } private void SetDirectionVisible(bool visible) @@ -143,6 +176,12 @@ public class ControlPanel : MonoBehaviour if (_directionDropdownGO != null) _directionDropdownGO.SetActive(visible); } + private void SetInputVisible(bool visible) + { + if (inputField != null && inputField.gameObject.activeSelf != visible) + inputField.gameObject.SetActive(visible); + } + private void CacheCurrentInput() { if (inputField == null) return; @@ -150,8 +189,7 @@ public class ControlPanel : MonoBehaviour if (_mode == Mode.DC) { _savedDCInput = inputField.text; - if (directionDropdown != null) - _savedDirectionIndex = directionDropdown.value; + if (directionDropdown != null) _savedDirectionIndex = directionDropdown.value; } else if (_mode == Mode.Display) { @@ -159,15 +197,11 @@ public class ControlPanel : MonoBehaviour } } - private void OnButtonClicked() + private void OnMainButtonClicked() { if (_mode == Mode.DC) { - if (_dc == null) - { - Debug.LogWarning("ControlPanel: No DC module selected."); - return; - } + if (_dc == null) return; if (!float.TryParse(inputField.text, out float degrees)) { @@ -180,14 +214,206 @@ public class ControlPanel : MonoBehaviour } else if (_mode == Mode.Display) { - if (_display == null) - { - Debug.LogWarning("ControlPanel: No Display module selected."); - return; - } - - string text = inputField != null ? inputField.text : ""; - _display.SetDisplayText(text); // <- THIS is where Display module gets the text + if (_display == null) return; + _display.SetDisplayText(inputField != null ? inputField.text : ""); + } + else if (_mode == Mode.Speaker) + { + if (_speaker == null) return; + _speaker.SendAudioToHardware(); // Send Audio = upload to hardware (your implementation) } } + + // ------------------------- + // Styling helpers (copy Send button look) + // ------------------------- + + private void CopyButtonStyle(Button source, Button target) + { + if (source == null || target == null) return; + + // Button settings + target.transition = source.transition; + target.colors = source.colors; + target.spriteState = source.spriteState; + target.navigation = source.navigation; + target.interactable = source.interactable; + + // Image settings + var srcImg = source.GetComponent(); + var dstImg = target.GetComponent(); + if (srcImg != null && dstImg != null) + { + dstImg.sprite = srcImg.sprite; + dstImg.type = srcImg.type; + dstImg.pixelsPerUnitMultiplier = srcImg.pixelsPerUnitMultiplier; + dstImg.material = srcImg.material; + dstImg.color = srcImg.color; + dstImg.raycastTarget = srcImg.raycastTarget; + } + } + + private void CopyTMPStyle(TextMeshProUGUI source, TextMeshProUGUI target) + { + if (source == null || target == null) return; + + target.font = source.font; + target.fontSharedMaterial = source.fontSharedMaterial; + target.fontStyle = source.fontStyle; + target.fontSize = source.fontSize; + target.enableAutoSizing = source.enableAutoSizing; + target.color = source.color; + target.enableVertexGradient = source.enableVertexGradient; + target.alignment = source.alignment; + target.enableWordWrapping = source.enableWordWrapping; + target.richText = source.richText; + } + + // ------------------------- + // Upload button (code-created) + // ------------------------- + + private void CreateUploadButtonIfNeeded() + { + if (_uploadButton != null) return; + + var go = new GameObject("UploadButton"); + go.transform.SetParent(transform, false); + + var img = go.AddComponent(); + img.raycastTarget = true; + + _uploadButton = go.AddComponent