using System; using ConformalDecals.Util; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; namespace ConformalDecals.UI { public class ColorPickerController : MonoBehaviour { [Serializable] public class ColorUpdateEvent : UnityEvent { } [Serializable] public class ChannelUpdateEvent : UnityEvent { } [Serializable] public class SVUpdateEvent : UnityEvent { } [SerializeField] public ColorUpdateEvent onColorChanged = new ColorUpdateEvent(); [SerializeField] private Color _value; [SerializeField] private Image _previewImage; [SerializeField] private Selectable _hexTextBox; private bool _ignoreUpdate; public Color RGB { get => _value; set { _value = value; OnColorUpdate(); } } public Util.ColorHSV HSV { get => Util.ColorHSV.RGB2HSV(_value); set { _value = Util.ColorHSV.HSV2RGB(value); OnColorUpdate(); } } public static ColorPickerController Create(Color rgb, UnityAction colorUpdateCallback) { var menu = Instantiate(UILoader.ColorPickerPrefab, MainCanvasUtil.MainCanvas.transform, true); menu.AddComponent(); MenuNavigation.SpawnMenuNavigation(menu, Navigation.Mode.Automatic, true); var controller = menu.GetComponent(); controller.RGB = rgb; controller.onColorChanged.AddListener(colorUpdateCallback); return controller; } public void Close() { Destroy(gameObject); } public void OnChannelUpdate(float value, int channel, bool hsv) { if (hsv) { var newHSV = HSV; newHSV[channel] = value; HSV = newHSV; } else { var newRGB = RGB; newRGB[channel] = value; RGB = newRGB; } } public void OnSVUpdate(Vector2 sv) { var newHSV = HSV; newHSV.s = sv.x; newHSV.v = sv.y; HSV = newHSV; } public void OnColorUpdate() { onColorChanged.Invoke(RGB, HSV); _previewImage.material.SetColor(PropertyIDs._Color, RGB); UpdateHexColor(); } public void OnHexColorUpdate(string text) { if (_ignoreUpdate) return; if (ParseUtil.TryParseHexColor(text, out var newRGB)) { RGB = newRGB; OnColorUpdate(); } else { UpdateHexColor(); } } private void Awake() { foreach (var slider in gameObject.GetComponentsInChildren()) { slider.onChannelChanged.AddListener(OnChannelUpdate); onColorChanged.AddListener(slider.OnColorUpdate); } foreach (var box in gameObject.GetComponentsInChildren()) { box.onValueChanged.AddListener(OnSVUpdate); onColorChanged.AddListener(box.OnColorUpdate); } } private void UpdateHexColor() { _ignoreUpdate = true; var byteColor = (Color32) RGB; var hexColor = $"{byteColor.r:x2}{byteColor.g:x2}{byteColor.b:x2}"; ((TMP_InputField) _hexTextBox).text = hexColor; _ignoreUpdate = false; } } }