Color picker UI code
parent
365dabc90f
commit
b1d6e43512
@ -0,0 +1,55 @@
|
||||
using ConformalDecals.Util;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace ConformalDecals.UI {
|
||||
public class ColorBoxSlider : MonoBehaviour {
|
||||
[SerializeField] private ColorPickerController.ChannelUpdateEvent _onXChannelChanged = new ColorPickerController.ChannelUpdateEvent();
|
||||
[SerializeField] private ColorPickerController.ChannelUpdateEvent _onYChannelChanged = new ColorPickerController.ChannelUpdateEvent();
|
||||
|
||||
[SerializeField] private Vector2 _value;
|
||||
[SerializeField] private Vector2Int _channel;
|
||||
[SerializeField] private bool _hsl;
|
||||
|
||||
[SerializeField] private BoxSlider _slider;
|
||||
[SerializeField] private Image _image;
|
||||
|
||||
private Material _imageMaterial;
|
||||
|
||||
public Vector2 Value {
|
||||
get => _value;
|
||||
set {
|
||||
_value.x = Mathf.Clamp01(value.x);
|
||||
_value.y = Mathf.Clamp01(value.y);
|
||||
UpdateSlider();
|
||||
OnChannelUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public void Awake() {
|
||||
_imageMaterial = _image.material;
|
||||
}
|
||||
|
||||
public void OnSliderUpdate(Vector2 value) {
|
||||
_value = value;
|
||||
OnChannelUpdate();
|
||||
}
|
||||
|
||||
public void OnChannelUpdate() {
|
||||
_onXChannelChanged.Invoke(_value.x, _channel.x, _hsl);
|
||||
_onYChannelChanged.Invoke(_value.y, _channel.y, _hsl);
|
||||
}
|
||||
|
||||
public void OnColorUpdate(Color rgb, ColorHSL hsl) {
|
||||
Vector2 newValue;
|
||||
_imageMaterial.SetColor(PropertyIDs._Color, rgb);
|
||||
newValue.x = _hsl ? hsl[_channel.x] : rgb[_channel.x];
|
||||
newValue.y = _hsl ? hsl[_channel.y] : rgb[_channel.y];
|
||||
Value = newValue;
|
||||
}
|
||||
|
||||
public void UpdateSlider() {
|
||||
_slider.Value = _value;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
using ConformalDecals.Util;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace ConformalDecals.UI {
|
||||
public class ColorChannelSlider : MonoBehaviour {
|
||||
[SerializeField] private ColorPickerController.ChannelUpdateEvent _onChannelChanged = new ColorPickerController.ChannelUpdateEvent();
|
||||
|
||||
[SerializeField] private float _value;
|
||||
[SerializeField] private int _channel;
|
||||
[SerializeField] private bool _hsl;
|
||||
|
||||
[SerializeField] private Selectable _textBox;
|
||||
[SerializeField] private Slider _slider;
|
||||
[SerializeField] private Image _image;
|
||||
|
||||
private Material _imageMaterial;
|
||||
|
||||
private bool _ignoreUpdates;
|
||||
|
||||
public float Value {
|
||||
get => _value;
|
||||
set {
|
||||
_value = Mathf.Clamp01(value);
|
||||
UpdateSlider();
|
||||
UpdateTextbox();
|
||||
OnChannelUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public void Awake() {
|
||||
_imageMaterial = _image.material;
|
||||
}
|
||||
|
||||
public void OnTextBoxUpdate(string text) {
|
||||
if (_ignoreUpdates) return;
|
||||
|
||||
if (byte.TryParse(text, out byte byteValue)) {
|
||||
_value = (float) byteValue / 255;
|
||||
UpdateSlider();
|
||||
OnChannelUpdate();
|
||||
}
|
||||
else {
|
||||
// value is invalid, reset value
|
||||
UpdateTextbox();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnSliderUpdate(float value) {
|
||||
if (_ignoreUpdates) return;
|
||||
|
||||
_value = value;
|
||||
UpdateTextbox();
|
||||
OnChannelUpdate();
|
||||
}
|
||||
|
||||
public void OnChannelUpdate() {
|
||||
_onChannelChanged.Invoke(_value, _channel, _hsl);
|
||||
}
|
||||
|
||||
public void OnColorUpdate(Color rgb, ColorHSL hsl) {
|
||||
_imageMaterial.SetColor(PropertyIDs._Color, rgb);
|
||||
Value = _hsl ? hsl[_channel] : rgb[_channel];
|
||||
}
|
||||
|
||||
public void UpdateSlider() {
|
||||
_ignoreUpdates = true;
|
||||
_slider.value = _value;
|
||||
_ignoreUpdates = false;
|
||||
}
|
||||
|
||||
public void UpdateTextbox() {
|
||||
if (_textBox == null) return;
|
||||
|
||||
_ignoreUpdates = true;
|
||||
((TMP_InputField) _textBox).text = ((byte) (255 * _value)).ToString();
|
||||
_ignoreUpdates = false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
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<Color, ColorHSL> { }
|
||||
|
||||
[Serializable]
|
||||
public class ChannelUpdateEvent : UnityEvent<float, int, bool> { }
|
||||
|
||||
[SerializeField] private 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 ColorHSL HSL {
|
||||
get => ColorHSL.RGB2HSL(_value);
|
||||
set {
|
||||
_value = ColorHSL.HSL2RGB(value);
|
||||
OnColorUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static ColorPickerController Create(Color rgb, UnityAction<Color, ColorHSL> colorUpdateCallback) {
|
||||
var menu = Instantiate(UILoader.ColorPickerPrefab, MainCanvasUtil.MainCanvas.transform, true);
|
||||
menu.AddComponent<DragPanel>();
|
||||
MenuNavigation.SpawnMenuNavigation(menu, Navigation.Mode.Automatic, true);
|
||||
|
||||
var controller = menu.GetComponent<ColorPickerController>();
|
||||
controller.RGB = rgb;
|
||||
controller._onColorChanged.AddListener(colorUpdateCallback);
|
||||
return controller;
|
||||
}
|
||||
|
||||
public void OnClose() {
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
public void OnColorUpdate() {
|
||||
_onColorChanged.Invoke(RGB, HSL);
|
||||
_previewImage.material.SetColor(PropertyIDs._Color, RGB);
|
||||
}
|
||||
|
||||
public void OnHexColorUpdate(string text) {
|
||||
if (_ignoreUpdate) return;
|
||||
|
||||
if (ParseUtil.TryParseHexColor(text, out var newRGB)) {
|
||||
RGB = newRGB;
|
||||
OnColorUpdate();
|
||||
}
|
||||
else {
|
||||
UpdateHexColor();
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateHexColor() {
|
||||
_ignoreUpdate = true;
|
||||
((TMP_InputField) _hexTextBox).text = $"{RGB.r:x2}{RGB.g:x2}{RGB.b:x2}";
|
||||
_ignoreUpdate = false;
|
||||
}
|
||||
|
||||
public void OnChannelUpdate(float value, int channel, bool hsl) {
|
||||
if (hsl) {
|
||||
var newHSL = HSL;
|
||||
newHSL[channel] = value;
|
||||
HSL = newHSL;
|
||||
}
|
||||
else {
|
||||
var newRGB = RGB;
|
||||
newRGB[channel] = value;
|
||||
RGB = newRGB;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue