281 lines
8.8 KiB
C#
281 lines
8.8 KiB
C#
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace FloodSWE.Networking
|
|
{
|
|
/// <summary>
|
|
/// Drives a Connect/Disconnect button from SweQuestControlClient state.
|
|
/// </summary>
|
|
public sealed class SweConnectionButtonController : MonoBehaviour
|
|
{
|
|
[Header("References")]
|
|
[SerializeField] private SweQuestControlClient controlClient;
|
|
[SerializeField] private Button button;
|
|
[SerializeField] private TMP_Text label;
|
|
[SerializeField] private TMP_InputField serverIpInput;
|
|
|
|
[Header("Labels")]
|
|
[SerializeField] private string connectLabel = "Connect";
|
|
[SerializeField] private string loadingLabel = "Loading...";
|
|
[SerializeField] private string disconnectLabel = "Disconnect";
|
|
|
|
[Header("Behavior")]
|
|
[SerializeField] private bool disableButtonWhileLoading = true;
|
|
[SerializeField] private bool allowCancelWhileLoading = false;
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (button == null)
|
|
{
|
|
button = GetComponent<Button>();
|
|
}
|
|
|
|
if (label == null && button != null)
|
|
{
|
|
label = button.GetComponentInChildren<TMP_Text>();
|
|
}
|
|
|
|
if (controlClient == null)
|
|
{
|
|
controlClient = FindFirstObjectByType<SweQuestControlClient>();
|
|
}
|
|
|
|
EnsureServerIpInput();
|
|
|
|
if (serverIpInput != null)
|
|
{
|
|
serverIpInput.onValueChanged.AddListener(OnServerIpChanged);
|
|
string serverHost = controlClient != null ? controlClient.serverHost : string.Empty;
|
|
serverIpInput.SetTextWithoutNotify(serverHost ?? string.Empty);
|
|
}
|
|
|
|
if (button != null)
|
|
{
|
|
button.onClick.AddListener(OnButtonPressed);
|
|
}
|
|
|
|
RefreshVisual();
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
if (serverIpInput != null)
|
|
{
|
|
serverIpInput.onValueChanged.RemoveListener(OnServerIpChanged);
|
|
}
|
|
|
|
if (button != null)
|
|
{
|
|
button.onClick.RemoveListener(OnButtonPressed);
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
RefreshVisual();
|
|
}
|
|
|
|
public void OnButtonPressed()
|
|
{
|
|
if (controlClient == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (controlClient.IsConnectionAlive)
|
|
{
|
|
controlClient.Disconnect();
|
|
return;
|
|
}
|
|
|
|
if (controlClient.IsWaitingForAck)
|
|
{
|
|
if (allowCancelWhileLoading)
|
|
{
|
|
controlClient.Disconnect();
|
|
}
|
|
return;
|
|
}
|
|
|
|
controlClient.Connect();
|
|
}
|
|
|
|
private void RefreshVisual()
|
|
{
|
|
if (controlClient == null)
|
|
{
|
|
SetLabel(connectLabel);
|
|
SetButtonInteractable(false);
|
|
return;
|
|
}
|
|
|
|
if (controlClient.IsConnectionAlive)
|
|
{
|
|
SetLabel(disconnectLabel);
|
|
SetButtonInteractable(true);
|
|
return;
|
|
}
|
|
|
|
if (controlClient.IsWaitingForAck)
|
|
{
|
|
SetLabel(loadingLabel);
|
|
bool interactable = !disableButtonWhileLoading || allowCancelWhileLoading;
|
|
SetButtonInteractable(interactable);
|
|
return;
|
|
}
|
|
|
|
SetLabel(connectLabel);
|
|
SetButtonInteractable(true);
|
|
}
|
|
|
|
private void SetLabel(string textValue)
|
|
{
|
|
if (label == null || label.text == textValue)
|
|
{
|
|
return;
|
|
}
|
|
|
|
label.text = textValue;
|
|
}
|
|
|
|
private void SetButtonInteractable(bool interactable)
|
|
{
|
|
if (button == null || button.interactable == interactable)
|
|
{
|
|
return;
|
|
}
|
|
|
|
button.interactable = interactable;
|
|
}
|
|
|
|
private void OnServerIpChanged(string serverIp)
|
|
{
|
|
if (controlClient == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
controlClient.serverHost = serverIp ?? string.Empty;
|
|
}
|
|
|
|
private void EnsureServerIpInput()
|
|
{
|
|
if (serverIpInput != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
RectTransform panelRect = transform.parent as RectTransform;
|
|
if (panelRect == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
TMP_InputField existingInput = panelRect.GetComponentInChildren<TMP_InputField>(true);
|
|
if (existingInput != null)
|
|
{
|
|
serverIpInput = existingInput;
|
|
return;
|
|
}
|
|
|
|
serverIpInput = CreateServerIpInput(panelRect);
|
|
}
|
|
|
|
private TMP_InputField CreateServerIpInput(RectTransform panelRect)
|
|
{
|
|
RectTransform buttonRect = button != null ? button.transform as RectTransform : null;
|
|
if (buttonRect != null)
|
|
{
|
|
buttonRect.anchoredPosition = new Vector2(buttonRect.anchoredPosition.x, -95.0f);
|
|
}
|
|
|
|
panelRect.sizeDelta = new Vector2(panelRect.sizeDelta.x, Mathf.Max(125.0f, panelRect.sizeDelta.y));
|
|
|
|
GameObject inputRoot = new GameObject(
|
|
"Server IP Input",
|
|
typeof(RectTransform),
|
|
typeof(CanvasRenderer),
|
|
typeof(Image),
|
|
typeof(TMP_InputField));
|
|
RectTransform inputRect = inputRoot.GetComponent<RectTransform>();
|
|
inputRect.SetParent(panelRect, false);
|
|
inputRect.anchorMin = new Vector2(0.0f, 1.0f);
|
|
inputRect.anchorMax = new Vector2(0.0f, 1.0f);
|
|
inputRect.pivot = new Vector2(0.0f, 1.0f);
|
|
inputRect.anchoredPosition = new Vector2(25.0f, -60.0f);
|
|
inputRect.sizeDelta = new Vector2(200.0f, 30.0f);
|
|
|
|
Image background = inputRoot.GetComponent<Image>();
|
|
background.color = new Color(1.0f, 1.0f, 1.0f, 0.95f);
|
|
|
|
GameObject textAreaObject = new GameObject("Text Area", typeof(RectTransform), typeof(RectMask2D));
|
|
RectTransform textAreaRect = textAreaObject.GetComponent<RectTransform>();
|
|
textAreaRect.SetParent(inputRect, false);
|
|
textAreaRect.anchorMin = Vector2.zero;
|
|
textAreaRect.anchorMax = Vector2.one;
|
|
textAreaRect.offsetMin = new Vector2(10.0f, 6.0f);
|
|
textAreaRect.offsetMax = new Vector2(-10.0f, -7.0f);
|
|
|
|
TMP_FontAsset fontAsset = label != null ? label.font : TMP_Settings.defaultFontAsset;
|
|
|
|
TextMeshProUGUI placeholder = CreateInputText(
|
|
"Placeholder",
|
|
textAreaRect,
|
|
fontAsset,
|
|
"Server IP",
|
|
new Color(0.45f, 0.45f, 0.45f, 0.9f));
|
|
placeholder.fontStyle = FontStyles.Italic;
|
|
|
|
TextMeshProUGUI inputText = CreateInputText(
|
|
"Text",
|
|
textAreaRect,
|
|
fontAsset,
|
|
string.Empty,
|
|
Color.black);
|
|
|
|
TMP_InputField inputField = inputRoot.GetComponent<TMP_InputField>();
|
|
inputField.targetGraphic = background;
|
|
inputField.textViewport = textAreaRect;
|
|
inputField.textComponent = inputText;
|
|
inputField.placeholder = placeholder;
|
|
inputField.lineType = TMP_InputField.LineType.SingleLine;
|
|
|
|
return inputField;
|
|
}
|
|
|
|
private static TextMeshProUGUI CreateInputText(
|
|
string objectName,
|
|
RectTransform parent,
|
|
TMP_FontAsset fontAsset,
|
|
string textValue,
|
|
Color textColor)
|
|
{
|
|
GameObject textObject = new GameObject(objectName, typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI));
|
|
RectTransform textRect = textObject.GetComponent<RectTransform>();
|
|
textRect.SetParent(parent, false);
|
|
textRect.anchorMin = Vector2.zero;
|
|
textRect.anchorMax = Vector2.one;
|
|
textRect.offsetMin = Vector2.zero;
|
|
textRect.offsetMax = Vector2.zero;
|
|
|
|
TextMeshProUGUI text = textObject.GetComponent<TextMeshProUGUI>();
|
|
text.font = fontAsset;
|
|
if (fontAsset != null)
|
|
{
|
|
text.fontSharedMaterial = fontAsset.material;
|
|
}
|
|
text.text = textValue;
|
|
text.color = textColor;
|
|
text.fontSize = 20.0f;
|
|
text.enableAutoSizing = true;
|
|
text.fontSizeMin = 14.0f;
|
|
text.fontSizeMax = 24.0f;
|
|
text.alignment = TextAlignmentOptions.Left;
|
|
text.enableWordWrapping = false;
|
|
text.raycastTarget = false;
|
|
return text;
|
|
}
|
|
}
|
|
}
|