mirror of
https://github.com/BotChain-Robots/ui.git
synced 2026-07-08 15:07:22 +02:00
Added rest of the modules
This commit is contained in:
@@ -5,40 +5,47 @@ using UnityEngine.UI;
|
|||||||
public class ControlPanel : MonoBehaviour
|
public class ControlPanel : MonoBehaviour
|
||||||
{
|
{
|
||||||
[Header("Core UI (assign in Inspector)")]
|
[Header("Core UI (assign in Inspector)")]
|
||||||
public TMP_InputField inputField; // was DegreesInputField
|
public TMP_InputField inputField;
|
||||||
public TMP_Dropdown directionDropdown; // was DirectionDropdown
|
public TMP_Dropdown directionDropdown;
|
||||||
public Button button; // was RotateButton
|
public Button button; // existing Send/Rotate button in hierarchy
|
||||||
|
|
||||||
private enum Mode { None, DC, Display, Gripper }
|
private enum Mode { None, DC, Display, Speaker }
|
||||||
private Mode _mode = Mode.None;
|
private Mode _mode = Mode.None;
|
||||||
|
|
||||||
private DCMotorModule _dc;
|
private DCMotorModule _dc;
|
||||||
private DisplayModule _display;
|
private DisplayModule _display;
|
||||||
private GripperModule _gripper;
|
private SpeakerModule _speaker;
|
||||||
|
|
||||||
// Keep separate inputs so they don't interfere
|
|
||||||
private string _savedDCInput = "";
|
private string _savedDCInput = "";
|
||||||
private int _savedDirectionIndex = 0;
|
private int _savedDirectionIndex = 0;
|
||||||
private string _savedDisplayInput = "";
|
private string _savedDisplayInput = "";
|
||||||
private string _savedGripperInput = "";
|
|
||||||
|
|
||||||
// Found automatically (no new UI objects)
|
// Found automatically (no hierarchy edits)
|
||||||
private TextMeshProUGUI _caption; // DegreesCaption text
|
private TextMeshProUGUI _caption; // child "DegreesCaption"
|
||||||
private TextMeshProUGUI _buttonText; // RotateButton/Text (TMP)
|
private TextMeshProUGUI _buttonText; // child "RotateButton/Text (TMP)"
|
||||||
private GameObject _directionCaptionGO; // DirectionCaption
|
private GameObject _directionCaptionGO;
|
||||||
private GameObject _directionDropdownGO; // DirectionDropdown GameObject
|
private GameObject _directionDropdownGO;
|
||||||
|
|
||||||
|
// Created in code (Speaker mode only)
|
||||||
|
private Button _uploadButton;
|
||||||
|
private TextMeshProUGUI _uploadButtonText;
|
||||||
|
private Button _playButton;
|
||||||
|
private TextMeshProUGUI _playButtonText;
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
CacheUIFromHierarchy();
|
CacheUIFromHierarchy();
|
||||||
|
|
||||||
|
// Create these once; hide unless Speaker mode
|
||||||
|
CreateUploadButtonIfNeeded();
|
||||||
|
CreatePlayButtonIfNeeded();
|
||||||
|
|
||||||
if (button != null)
|
if (button != null)
|
||||||
{
|
{
|
||||||
button.onClick.RemoveAllListeners();
|
button.onClick.RemoveAllListeners();
|
||||||
button.onClick.AddListener(OnButtonClicked);
|
button.onClick.AddListener(OnMainButtonClicked);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache typed values so switching modules restores what you typed
|
|
||||||
if (inputField != null)
|
if (inputField != null)
|
||||||
{
|
{
|
||||||
inputField.onValueChanged.AddListener(_ => CacheCurrentInput());
|
inputField.onValueChanged.AddListener(_ => CacheCurrentInput());
|
||||||
@@ -54,37 +61,17 @@ public class ControlPanel : MonoBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Call this whenever a DC or Display module is selected.
|
|
||||||
/// </summary>
|
|
||||||
public void Initialize(ModuleBase module)
|
public void Initialize(ModuleBase module)
|
||||||
{
|
{
|
||||||
CacheCurrentInput();
|
CacheCurrentInput();
|
||||||
|
|
||||||
_dc = module as DCMotorModule;
|
_dc = module as DCMotorModule;
|
||||||
_display = module as DisplayModule;
|
_display = module as DisplayModule;
|
||||||
_gripper = module as GripperModule;
|
_speaker = module as SpeakerModule;
|
||||||
|
|
||||||
if (_dc != null)
|
if (_dc != null) { SwitchMode(Mode.DC); gameObject.SetActive(true); return; }
|
||||||
{
|
if (_display != null) { SwitchMode(Mode.Display); gameObject.SetActive(true); return; }
|
||||||
SwitchMode(Mode.DC);
|
if (_speaker != null) { SwitchMode(Mode.Speaker); gameObject.SetActive(true); return; }
|
||||||
gameObject.SetActive(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_display != null)
|
|
||||||
{
|
|
||||||
SwitchMode(Mode.Display);
|
|
||||||
gameObject.SetActive(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_gripper != null)
|
|
||||||
{
|
|
||||||
SwitchMode(Mode.Gripper);
|
|
||||||
gameObject.SetActive(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
HidePanel();
|
HidePanel();
|
||||||
}
|
}
|
||||||
@@ -96,12 +83,13 @@ public class ControlPanel : MonoBehaviour
|
|||||||
_mode = Mode.None;
|
_mode = Mode.None;
|
||||||
_dc = null;
|
_dc = null;
|
||||||
_display = null;
|
_display = null;
|
||||||
_gripper = null;
|
_speaker = null;
|
||||||
|
SetUploadVisible(false);
|
||||||
|
SetPlayVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CacheUIFromHierarchy()
|
private void CacheUIFromHierarchy()
|
||||||
{
|
{
|
||||||
// Assumes this script is on the parent that contains these children
|
|
||||||
var captionT = transform.Find("DegreesCaption");
|
var captionT = transform.Find("DegreesCaption");
|
||||||
if (captionT != null) _caption = captionT.GetComponent<TextMeshProUGUI>();
|
if (captionT != null) _caption = captionT.GetComponent<TextMeshProUGUI>();
|
||||||
|
|
||||||
@@ -122,39 +110,64 @@ public class ControlPanel : MonoBehaviour
|
|||||||
|
|
||||||
if (_mode == Mode.DC)
|
if (_mode == Mode.DC)
|
||||||
{
|
{
|
||||||
if (_caption != null) _caption.text = "Degrees";
|
SetCaption("Degrees");
|
||||||
if (_buttonText != null) _buttonText.text = "Rotate";
|
SetCaptionVisible(true);
|
||||||
|
SetMainButtonText("Rotate");
|
||||||
SetDirectionVisible(true);
|
SetDirectionVisible(true);
|
||||||
|
SetInputVisible(true);
|
||||||
|
SetUploadVisible(false);
|
||||||
|
SetPlayVisible(false);
|
||||||
|
|
||||||
if (inputField != null)
|
if (inputField != null)
|
||||||
|
{
|
||||||
|
inputField.readOnly = false;
|
||||||
inputField.SetTextWithoutNotify(_savedDCInput);
|
inputField.SetTextWithoutNotify(_savedDCInput);
|
||||||
|
}
|
||||||
|
|
||||||
if (directionDropdown != null)
|
if (directionDropdown != null)
|
||||||
directionDropdown.SetValueWithoutNotify(_savedDirectionIndex);
|
directionDropdown.SetValueWithoutNotify(_savedDirectionIndex);
|
||||||
}
|
}
|
||||||
else if (_mode == Mode.Display)
|
else if (_mode == Mode.Display)
|
||||||
{
|
{
|
||||||
if (_caption != null) _caption.text = "Text";
|
SetCaption("Text");
|
||||||
if (_buttonText != null) _buttonText.text = "Send";
|
SetCaptionVisible(true);
|
||||||
|
SetMainButtonText("Send");
|
||||||
SetDirectionVisible(false);
|
SetDirectionVisible(false);
|
||||||
|
SetInputVisible(true);
|
||||||
|
SetUploadVisible(false);
|
||||||
|
SetPlayVisible(false);
|
||||||
|
|
||||||
// Prefer module's current displayText; fallback to last typed text
|
if (inputField != null)
|
||||||
|
{
|
||||||
|
inputField.readOnly = false;
|
||||||
string toShow = _savedDisplayInput;
|
string toShow = _savedDisplayInput;
|
||||||
if (_display != null && !string.IsNullOrEmpty(_display.displayText))
|
if (_display != null && !string.IsNullOrEmpty(_display.displayText))
|
||||||
toShow = _display.displayText;
|
toShow = _display.displayText;
|
||||||
|
|
||||||
if (inputField != null)
|
|
||||||
inputField.SetTextWithoutNotify(toShow);
|
inputField.SetTextWithoutNotify(toShow);
|
||||||
}
|
}
|
||||||
else if (_mode == Mode.Gripper)
|
|
||||||
{
|
|
||||||
if (_caption != null) _caption.text = "Degrees";
|
|
||||||
if (_buttonText != null) _buttonText.text = "Apply";
|
|
||||||
SetDirectionVisible(false);
|
|
||||||
|
|
||||||
if (inputField != null)
|
|
||||||
inputField.SetTextWithoutNotify(_gripper != null ? _gripper.currentAngle.ToString("F0") : _savedGripperInput);
|
|
||||||
}
|
}
|
||||||
|
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)
|
private void SetDirectionVisible(bool visible)
|
||||||
@@ -163,6 +176,12 @@ public class ControlPanel : MonoBehaviour
|
|||||||
if (_directionDropdownGO != null) _directionDropdownGO.SetActive(visible);
|
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()
|
private void CacheCurrentInput()
|
||||||
{
|
{
|
||||||
if (inputField == null) return;
|
if (inputField == null) return;
|
||||||
@@ -170,28 +189,19 @@ public class ControlPanel : MonoBehaviour
|
|||||||
if (_mode == Mode.DC)
|
if (_mode == Mode.DC)
|
||||||
{
|
{
|
||||||
_savedDCInput = inputField.text;
|
_savedDCInput = inputField.text;
|
||||||
if (directionDropdown != null)
|
if (directionDropdown != null) _savedDirectionIndex = directionDropdown.value;
|
||||||
_savedDirectionIndex = directionDropdown.value;
|
|
||||||
}
|
}
|
||||||
else if (_mode == Mode.Display)
|
else if (_mode == Mode.Display)
|
||||||
{
|
{
|
||||||
_savedDisplayInput = inputField.text;
|
_savedDisplayInput = inputField.text;
|
||||||
}
|
}
|
||||||
else if (_mode == Mode.Gripper)
|
|
||||||
{
|
|
||||||
_savedGripperInput = inputField.text;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnButtonClicked()
|
private void OnMainButtonClicked()
|
||||||
{
|
{
|
||||||
if (_mode == Mode.DC)
|
if (_mode == Mode.DC)
|
||||||
{
|
{
|
||||||
if (_dc == null)
|
if (_dc == null) return;
|
||||||
{
|
|
||||||
Debug.LogWarning("ControlPanel: No DC module selected.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!float.TryParse(inputField.text, out float degrees))
|
if (!float.TryParse(inputField.text, out float degrees))
|
||||||
{
|
{
|
||||||
@@ -204,30 +214,206 @@ public class ControlPanel : MonoBehaviour
|
|||||||
}
|
}
|
||||||
else if (_mode == Mode.Display)
|
else if (_mode == Mode.Display)
|
||||||
{
|
{
|
||||||
if (_display == null)
|
if (_display == null) return;
|
||||||
|
_display.SetDisplayText(inputField != null ? inputField.text : "");
|
||||||
|
}
|
||||||
|
else if (_mode == Mode.Speaker)
|
||||||
{
|
{
|
||||||
Debug.LogWarning("ControlPanel: No Display module selected.");
|
if (_speaker == null) return;
|
||||||
return;
|
_speaker.SendAudioToHardware(); // Send Audio = upload to hardware (your implementation)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string text = inputField != null ? inputField.text : "";
|
// -------------------------
|
||||||
_display.SetDisplayText(text); // <- THIS is where Display module gets the text
|
// 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<Image>();
|
||||||
|
var dstImg = target.GetComponent<Image>();
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
else if (_mode == Mode.Gripper)
|
|
||||||
{
|
|
||||||
if (_gripper == null)
|
|
||||||
{
|
|
||||||
Debug.LogWarning("ControlPanel: No Gripper module selected.");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!float.TryParse(inputField.text, out float degrees))
|
private void CopyTMPStyle(TextMeshProUGUI source, TextMeshProUGUI target)
|
||||||
{
|
{
|
||||||
Debug.LogWarning("ControlPanel: Invalid degree input for Gripper.");
|
if (source == null || target == null) return;
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
_gripper.SetAngleAndSendControlLibrary(Mathf.Clamp(degrees, 0f, 180f));
|
// -------------------------
|
||||||
|
// 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<Image>();
|
||||||
|
img.raycastTarget = true;
|
||||||
|
|
||||||
|
_uploadButton = go.AddComponent<Button>();
|
||||||
|
_uploadButton.onClick.AddListener(OnUploadClicked);
|
||||||
|
|
||||||
|
// Copy Send button look
|
||||||
|
CopyButtonStyle(button, _uploadButton);
|
||||||
|
|
||||||
|
var textGo = new GameObject("Text (TMP)");
|
||||||
|
textGo.transform.SetParent(go.transform, false);
|
||||||
|
_uploadButtonText = textGo.AddComponent<TextMeshProUGUI>();
|
||||||
|
_uploadButtonText.text = "Upload Audio";
|
||||||
|
|
||||||
|
// Copy Send text look
|
||||||
|
CopyTMPStyle(_buttonText, _uploadButtonText);
|
||||||
|
_uploadButtonText.alignment = TextAlignmentOptions.Center;
|
||||||
|
|
||||||
|
// Layout: above Play
|
||||||
|
var rt = go.GetComponent<RectTransform>();
|
||||||
|
rt.anchorMin = new Vector2(0.5f, 0f);
|
||||||
|
rt.anchorMax = new Vector2(0.5f, 0f);
|
||||||
|
rt.pivot = new Vector2(0.5f, 0f);
|
||||||
|
rt.sizeDelta = button != null ? button.GetComponent<RectTransform>().sizeDelta : new Vector2(180f, 40f);
|
||||||
|
rt.anchoredPosition = new Vector2(0f, 110f);
|
||||||
|
|
||||||
|
var trt = textGo.GetComponent<RectTransform>();
|
||||||
|
trt.anchorMin = Vector2.zero;
|
||||||
|
trt.anchorMax = Vector2.one;
|
||||||
|
trt.offsetMin = Vector2.zero;
|
||||||
|
trt.offsetMax = Vector2.zero;
|
||||||
|
|
||||||
|
go.SetActive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SetUploadVisible(bool visible)
|
||||||
|
{
|
||||||
|
if (_uploadButton != null && _uploadButton.gameObject.activeSelf != visible)
|
||||||
|
_uploadButton.gameObject.SetActive(visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnUploadClicked()
|
||||||
|
{
|
||||||
|
if (_speaker == null) return;
|
||||||
|
|
||||||
|
string path = OpenAudioFilePicker();
|
||||||
|
if (string.IsNullOrEmpty(path)) return;
|
||||||
|
|
||||||
|
_speaker.SetAudioFile(path);
|
||||||
|
// If you want to display filename somewhere without the input field,
|
||||||
|
// we can put it in the caption temporarily or add a TMP label in code.
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// Play button (code-created)
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
private void CreatePlayButtonIfNeeded()
|
||||||
|
{
|
||||||
|
if (_playButton != null) return;
|
||||||
|
|
||||||
|
var go = new GameObject("PlayButton");
|
||||||
|
go.transform.SetParent(transform, false);
|
||||||
|
|
||||||
|
var img = go.AddComponent<Image>();
|
||||||
|
img.raycastTarget = true;
|
||||||
|
|
||||||
|
_playButton = go.AddComponent<Button>();
|
||||||
|
_playButton.onClick.AddListener(OnPlayClicked);
|
||||||
|
|
||||||
|
// Copy Send button look
|
||||||
|
CopyButtonStyle(button, _playButton);
|
||||||
|
|
||||||
|
var textGo = new GameObject("Text (TMP)");
|
||||||
|
textGo.transform.SetParent(go.transform, false);
|
||||||
|
_playButtonText = textGo.AddComponent<TextMeshProUGUI>();
|
||||||
|
_playButtonText.text = "Play Audio";
|
||||||
|
|
||||||
|
// Copy Send text look
|
||||||
|
CopyTMPStyle(_buttonText, _playButtonText);
|
||||||
|
_playButtonText.alignment = TextAlignmentOptions.Center;
|
||||||
|
|
||||||
|
// Layout: between Upload and Send
|
||||||
|
var rt = go.GetComponent<RectTransform>();
|
||||||
|
rt.anchorMin = new Vector2(0.5f, 0f);
|
||||||
|
rt.anchorMax = new Vector2(0.5f, 0f);
|
||||||
|
rt.pivot = new Vector2(0.5f, 0f);
|
||||||
|
rt.sizeDelta = button != null ? button.GetComponent<RectTransform>().sizeDelta : new Vector2(180f, 40f);
|
||||||
|
rt.anchoredPosition = new Vector2(0f, 60f);
|
||||||
|
|
||||||
|
var trt = textGo.GetComponent<RectTransform>();
|
||||||
|
trt.anchorMin = Vector2.zero;
|
||||||
|
trt.anchorMax = Vector2.one;
|
||||||
|
trt.offsetMin = Vector2.zero;
|
||||||
|
trt.offsetMax = Vector2.zero;
|
||||||
|
|
||||||
|
go.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetPlayVisible(bool visible)
|
||||||
|
{
|
||||||
|
if (_playButton != null && _playButton.gameObject.activeSelf != visible)
|
||||||
|
_playButton.gameObject.SetActive(visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPlayClicked()
|
||||||
|
{
|
||||||
|
if (_speaker == null) return;
|
||||||
|
_speaker.PlayAudioOnHardware();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// File Picker (Editor + builds via SFB)
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
private string OpenAudioFilePicker()
|
||||||
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
return UnityEditor.EditorUtility.OpenFilePanel("Select audio file", "", "wav,mp3,ogg");
|
||||||
|
#else
|
||||||
|
var extensions = new[]
|
||||||
|
{
|
||||||
|
new SFB.ExtensionFilter("Audio Files", "wav", "mp3", "ogg"),
|
||||||
|
new SFB.ExtensionFilter("All Files", "*")
|
||||||
|
};
|
||||||
|
|
||||||
|
string[] paths = SFB.StandaloneFileBrowser.OpenFilePanel("Select audio file", "", extensions, false);
|
||||||
|
return (paths != null && paths.Length > 0) ? paths[0] : "";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetCaptionVisible(bool visible)
|
||||||
|
{
|
||||||
|
if (_caption != null && _caption.gameObject.activeSelf != visible)
|
||||||
|
_caption.gameObject.SetActive(visible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,14 +23,12 @@ public class LiveViewModulePanel : MonoBehaviour
|
|||||||
|
|
||||||
private bool _sliderDragging;
|
private bool _sliderDragging;
|
||||||
private ControlPanel panel;
|
private ControlPanel panel;
|
||||||
private ModuleBase _lastSelected;
|
|
||||||
private GameObject sensorTextContainer;
|
private GameObject sensorTextContainer;
|
||||||
private readonly System.Collections.Generic.List<TextMeshProUGUI> sensorTextLines = new System.Collections.Generic.List<TextMeshProUGUI>();
|
private readonly System.Collections.Generic.List<TextMeshProUGUI> sensorTextLines = new System.Collections.Generic.List<TextMeshProUGUI>();
|
||||||
|
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
CreateSensorTextUI();
|
CreateSensorTextUI();
|
||||||
ApplyRoundedCornersToPanel();
|
|
||||||
|
|
||||||
if (servoAngleSlider != null)
|
if (servoAngleSlider != null)
|
||||||
{
|
{
|
||||||
@@ -38,7 +36,6 @@ public class LiveViewModulePanel : MonoBehaviour
|
|||||||
servoAngleSlider.maxValue = 180f;
|
servoAngleSlider.maxValue = 180f;
|
||||||
servoAngleSlider.direction = Slider.Direction.BottomToTop;
|
servoAngleSlider.direction = Slider.Direction.BottomToTop;
|
||||||
servoAngleSlider.onValueChanged.AddListener(OnServoSliderChanged);
|
servoAngleSlider.onValueChanged.AddListener(OnServoSliderChanged);
|
||||||
ConfigureSliderForVertical(servoAngleSlider);
|
|
||||||
|
|
||||||
var et = servoAngleSlider.GetComponent<EventTrigger>() ?? servoAngleSlider.gameObject.AddComponent<EventTrigger>();
|
var et = servoAngleSlider.GetComponent<EventTrigger>() ?? servoAngleSlider.gameObject.AddComponent<EventTrigger>();
|
||||||
var begin = new EventTrigger.Entry { eventID = EventTriggerType.BeginDrag };
|
var begin = new EventTrigger.Entry { eventID = EventTriggerType.BeginDrag };
|
||||||
@@ -69,7 +66,6 @@ public class LiveViewModulePanel : MonoBehaviour
|
|||||||
|
|
||||||
if (selected == null)
|
if (selected == null)
|
||||||
{
|
{
|
||||||
_lastSelected = null;
|
|
||||||
SetModuleInfo("No module selected");
|
SetModuleInfo("No module selected");
|
||||||
SetServoSectionActive(false);
|
SetServoSectionActive(false);
|
||||||
SetModuleControlSectionActive(false);
|
SetModuleControlSectionActive(false);
|
||||||
@@ -87,6 +83,7 @@ public class LiveViewModulePanel : MonoBehaviour
|
|||||||
var display = selected as DisplayModule;
|
var display = selected as DisplayModule;
|
||||||
var distance = selected as DistanceSensorModule;
|
var distance = selected as DistanceSensorModule;
|
||||||
var imu = selected as IMUSensorModule;
|
var imu = selected as IMUSensorModule;
|
||||||
|
var speaker = selected as SpeakerModule;
|
||||||
|
|
||||||
if (servo != null)
|
if (servo != null)
|
||||||
{
|
{
|
||||||
@@ -120,20 +117,13 @@ public class LiveViewModulePanel : MonoBehaviour
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DC, Display, or Gripper use the same control section (degrees input + button)
|
// DC or Display both use the same control section
|
||||||
var gripper = selected as GripperModule;
|
if (dc != null || display != null || speaker != null)
|
||||||
if (dc != null || display != null || gripper != null)
|
|
||||||
{
|
{
|
||||||
SetServoSectionActive(false);
|
SetServoSectionActive(false);
|
||||||
SetModuleControlSectionActive(true);
|
SetModuleControlSectionActive(true);
|
||||||
SetSensorTextActive(false);
|
|
||||||
|
|
||||||
if (selected != _lastSelected)
|
|
||||||
{
|
|
||||||
_lastSelected = selected;
|
|
||||||
panel?.Initialize(selected);
|
panel?.Initialize(selected);
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,16 +133,6 @@ public class LiveViewModulePanel : MonoBehaviour
|
|||||||
SetSensorTextActive(false);
|
SetSensorTextActive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyRoundedCornersToPanel()
|
|
||||||
{
|
|
||||||
var img = GetComponent<Image>();
|
|
||||||
if (img != null && img.sprite == null)
|
|
||||||
{
|
|
||||||
img.sprite = UIRoundedSprite.GetRoundedRectSprite();
|
|
||||||
img.type = Image.Type.Sliced; // 9-slice keeps corners rounded when panel stretches
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetModuleControlSectionActive(bool active)
|
void SetModuleControlSectionActive(bool active)
|
||||||
{
|
{
|
||||||
if (moduleControlSection == null || panel == null) return;
|
if (moduleControlSection == null || panel == null) return;
|
||||||
@@ -181,59 +161,6 @@ public class LiveViewModulePanel : MonoBehaviour
|
|||||||
ServoMotorModule.selectedModule.SetAngleAndSendControlLibrary(value);
|
ServoMotorModule.selectedModule.SetAngleAndSendControlLibrary(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureSliderForVertical(Slider slider)
|
|
||||||
{
|
|
||||||
if (slider == null || servoControlSection == null) return;
|
|
||||||
var sectionRect = servoControlSection.GetComponent<RectTransform>();
|
|
||||||
if (sectionRect != null)
|
|
||||||
EnsureDegreeLabels(sectionRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnsureDegreeLabels(RectTransform sectionRect)
|
|
||||||
{
|
|
||||||
SetDegreeLabel(sectionRect, "0deg", "0", 0, 14);
|
|
||||||
SetDegreeLabel(sectionRect, "180deg", "180", 1, -14);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetDegreeLabel(RectTransform sectionRect, string goName, string text, float anchorY, float posY)
|
|
||||||
{
|
|
||||||
var t = sectionRect.Find(goName);
|
|
||||||
if (t == null)
|
|
||||||
{
|
|
||||||
var go = new GameObject(goName);
|
|
||||||
go.transform.SetParent(sectionRect, false);
|
|
||||||
var tmp = go.AddComponent<TextMeshProUGUI>();
|
|
||||||
tmp.text = text;
|
|
||||||
tmp.fontSize = 16;
|
|
||||||
tmp.color = Color.white;
|
|
||||||
tmp.alignment = TextAlignmentOptions.MidlineLeft;
|
|
||||||
var r = go.GetComponent<RectTransform>();
|
|
||||||
r.anchorMin = new Vector2(1f, anchorY);
|
|
||||||
r.anchorMax = new Vector2(1f, anchorY);
|
|
||||||
r.pivot = new Vector2(0f, 0.5f);
|
|
||||||
r.anchoredPosition = new Vector2(20, posY);
|
|
||||||
r.sizeDelta = new Vector2(50, 24);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var tmp = t.GetComponent<TextMeshProUGUI>();
|
|
||||||
if (tmp != null)
|
|
||||||
{
|
|
||||||
tmp.color = Color.white;
|
|
||||||
tmp.fontSize = 16;
|
|
||||||
}
|
|
||||||
var r = t.GetComponent<RectTransform>();
|
|
||||||
if (r != null)
|
|
||||||
{
|
|
||||||
r.anchorMin = new Vector2(1f, anchorY);
|
|
||||||
r.anchorMax = new Vector2(1f, anchorY);
|
|
||||||
r.pivot = new Vector2(0f, 0.5f);
|
|
||||||
r.anchoredPosition = new Vector2(20, posY);
|
|
||||||
r.sizeDelta = new Vector2(50, 24);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateSensorTextUI()
|
void CreateSensorTextUI()
|
||||||
{
|
{
|
||||||
if (moduleInfoText == null) return;
|
if (moduleInfoText == null) return;
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ public class ModuleSpawner : MonoBehaviour
|
|||||||
public GameObject distanceSensorModulePrefab;
|
public GameObject distanceSensorModulePrefab;
|
||||||
public GameObject imuSensorModulePrefab;
|
public GameObject imuSensorModulePrefab;
|
||||||
public GameObject speakerModulePrefab;
|
public GameObject speakerModulePrefab;
|
||||||
public GameObject powerModulePrefab;
|
|
||||||
|
|
||||||
public GameObject GetPrefabForType(ModuleType type)
|
public GameObject GetPrefabForType(ModuleType type)
|
||||||
{
|
{
|
||||||
@@ -26,12 +25,10 @@ public class ModuleSpawner : MonoBehaviour
|
|||||||
{
|
{
|
||||||
case ModuleType.BATTERY:
|
case ModuleType.BATTERY:
|
||||||
return batteryModulePrefab;
|
return batteryModulePrefab;
|
||||||
case ModuleType.POWER:
|
|
||||||
return powerModulePrefab;
|
|
||||||
case ModuleType.SPLITTER:
|
case ModuleType.SPLITTER:
|
||||||
return hubModuleMMMFPrefab;
|
return hubModuleMMMFPrefab;
|
||||||
case ModuleType.DC_MOTOR:
|
case ModuleType.DC_MOTOR:
|
||||||
return null; // DC module deactivated
|
return dcMotorModulePrefab; // DC module deactivated
|
||||||
case ModuleType.SERVO_1:
|
case ModuleType.SERVO_1:
|
||||||
return servoBendModulePrefab;
|
return servoBendModulePrefab;
|
||||||
case ModuleType.SERVO_2:
|
case ModuleType.SERVO_2:
|
||||||
|
|||||||
@@ -4093,6 +4093,11 @@ Transform:
|
|||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 1319424261}
|
m_Father: {fileID: 1319424261}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: -90, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: -90, z: 0}
|
||||||
|
--- !u!4 &907893356 stripped
|
||||||
|
Transform:
|
||||||
|
m_CorrespondingSourceObject: {fileID: 5278868739616043210, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
|
||||||
|
m_PrefabInstance: {fileID: 1309657867}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
--- !u!1 &910000001
|
--- !u!1 &910000001
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -4664,7 +4669,10 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
m_RemovedComponents: []
|
m_RemovedComponents: []
|
||||||
m_RemovedGameObjects: []
|
m_RemovedGameObjects: []
|
||||||
m_AddedGameObjects: []
|
m_AddedGameObjects:
|
||||||
|
- targetCorrespondingSourceObject: {fileID: 4077927847297772526, guid: 46058ab5ebab64d548b4008f54df1f6d, type: 3}
|
||||||
|
insertIndex: -1
|
||||||
|
addedObject: {fileID: 907893356}
|
||||||
m_AddedComponents: []
|
m_AddedComponents: []
|
||||||
m_SourcePrefab: {fileID: 100100000, guid: 46058ab5ebab64d548b4008f54df1f6d, type: 3}
|
m_SourcePrefab: {fileID: 100100000, guid: 46058ab5ebab64d548b4008f54df1f6d, type: 3}
|
||||||
--- !u!1 &943453643
|
--- !u!1 &943453643
|
||||||
@@ -9535,8 +9543,7 @@ MonoBehaviour:
|
|||||||
displayModulePrefab: {fileID: 9087040773434933035, guid: 1d13960332e6840458c2d63f616e2774, type: 3}
|
displayModulePrefab: {fileID: 9087040773434933035, guid: 1d13960332e6840458c2d63f616e2774, type: 3}
|
||||||
distanceSensorModulePrefab: {fileID: 4820635649742989172, guid: 71a1ec0b30283422eafea6e72a83d947, type: 3}
|
distanceSensorModulePrefab: {fileID: 4820635649742989172, guid: 71a1ec0b30283422eafea6e72a83d947, type: 3}
|
||||||
imuSensorModulePrefab: {fileID: 7670757311786442011, guid: 78f1dcd3d1ad14720bec24368d935b13, type: 3}
|
imuSensorModulePrefab: {fileID: 7670757311786442011, guid: 78f1dcd3d1ad14720bec24368d935b13, type: 3}
|
||||||
speakerModulePrefab: {fileID: 0}
|
speakerModulePrefab: {fileID: 7364806464279017071, guid: 8bcdcbcb5a03245248cb7f883e80d948, type: 3}
|
||||||
powerModulePrefab: {fileID: 0}
|
|
||||||
--- !u!4 &2021810912
|
--- !u!4 &2021810912
|
||||||
Transform:
|
Transform:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -10415,4 +10422,3 @@ SceneRoots:
|
|||||||
- {fileID: 2031445727}
|
- {fileID: 2031445727}
|
||||||
- {fileID: 859822641}
|
- {fileID: 859822641}
|
||||||
- {fileID: 1319424261}
|
- {fileID: 1319424261}
|
||||||
- {fileID: 1309657867}
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -11,9 +11,7 @@ Material:
|
|||||||
m_Shader: {fileID: 45, guid: 0000000000000000f000000000000000, type: 0}
|
m_Shader: {fileID: 45, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
m_Parent: {fileID: 0}
|
m_Parent: {fileID: 0}
|
||||||
m_ModifiedSerializedProperties: 0
|
m_ModifiedSerializedProperties: 0
|
||||||
m_ValidKeywords:
|
m_ValidKeywords: []
|
||||||
- _NORMALMAP
|
|
||||||
- _SPECGLOSSMAP
|
|
||||||
m_InvalidKeywords: []
|
m_InvalidKeywords: []
|
||||||
m_LightmapFlags: 4
|
m_LightmapFlags: 4
|
||||||
m_EnableInstancingVariants: 1
|
m_EnableInstancingVariants: 1
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ Material:
|
|||||||
m_Shader: {fileID: 45, guid: 0000000000000000f000000000000000, type: 0}
|
m_Shader: {fileID: 45, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
m_Parent: {fileID: 0}
|
m_Parent: {fileID: 0}
|
||||||
m_ModifiedSerializedProperties: 0
|
m_ModifiedSerializedProperties: 0
|
||||||
m_ValidKeywords:
|
m_ValidKeywords: []
|
||||||
- _NORMALMAP
|
|
||||||
- _SPECGLOSSMAP
|
|
||||||
m_InvalidKeywords: []
|
m_InvalidKeywords: []
|
||||||
m_LightmapFlags: 4
|
m_LightmapFlags: 4
|
||||||
m_EnableInstancingVariants: 1
|
m_EnableInstancingVariants: 1
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ Material:
|
|||||||
m_Shader: {fileID: 45, guid: 0000000000000000f000000000000000, type: 0}
|
m_Shader: {fileID: 45, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
m_Parent: {fileID: 0}
|
m_Parent: {fileID: 0}
|
||||||
m_ModifiedSerializedProperties: 0
|
m_ModifiedSerializedProperties: 0
|
||||||
m_ValidKeywords:
|
m_ValidKeywords: []
|
||||||
- _NORMALMAP
|
|
||||||
- _SPECGLOSSMAP
|
|
||||||
m_InvalidKeywords: []
|
m_InvalidKeywords: []
|
||||||
m_LightmapFlags: 4
|
m_LightmapFlags: 4
|
||||||
m_EnableInstancingVariants: 1
|
m_EnableInstancingVariants: 1
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ Material:
|
|||||||
m_Shader: {fileID: 45, guid: 0000000000000000f000000000000000, type: 0}
|
m_Shader: {fileID: 45, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
m_Parent: {fileID: 0}
|
m_Parent: {fileID: 0}
|
||||||
m_ModifiedSerializedProperties: 0
|
m_ModifiedSerializedProperties: 0
|
||||||
m_ValidKeywords:
|
m_ValidKeywords: []
|
||||||
- _NORMALMAP
|
|
||||||
- _SPECGLOSSMAP
|
|
||||||
m_InvalidKeywords: []
|
m_InvalidKeywords: []
|
||||||
m_LightmapFlags: 4
|
m_LightmapFlags: 4
|
||||||
m_EnableInstancingVariants: 1
|
m_EnableInstancingVariants: 1
|
||||||
|
|||||||
Reference in New Issue
Block a user