mirror of
https://github.com/drewcassidy/KSP-Conformal-Decals.git
synced 2024-09-01 18:23:54 +00:00
Color picker UI code
This commit is contained in:
parent
365dabc90f
commit
b1d6e43512
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
<Import Project="$(MSBuildExtensionsPath)/$(MSBuildToolsVersion)/Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)/$(MSBuildToolsVersion)/Microsoft.Common.props')" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<Optimize>false</Optimize>
|
<Optimize>false</Optimize>
|
||||||
<OutputPath>bin\Debug\</OutputPath>
|
<OutputPath>bin/Debug/</OutputPath>
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
@ -25,11 +25,11 @@
|
|||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
<Optimize>true</Optimize>
|
<Optimize>true</Optimize>
|
||||||
<OutputPath>bin\Release\</OutputPath>
|
<OutputPath>bin/Release/</OutputPath>
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<DocumentationFile>bin\Release\ConformalDecals.xml</DocumentationFile>
|
<DocumentationFile>bin/Release/ConformalDecals.xml</DocumentationFile>
|
||||||
<NoWarn>CS1591,CS0649</NoWarn>
|
<NoWarn>CS1591,CS0649</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -41,65 +41,69 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
<Reference Include="UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||||
<HintPath>dlls\UnityEngine.dll</HintPath>
|
<HintPath>dlls/UnityEngine.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="UnityEngine.AssetBundleModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
<Reference Include="UnityEngine.AssetBundleModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||||
<HintPath>dlls\UnityEngine.AssetBundleModule.dll</HintPath>
|
<HintPath>dlls/UnityEngine.AssetBundleModule.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
<Reference Include="UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||||
<HintPath>dlls\UnityEngine.CoreModule.dll</HintPath>
|
<HintPath>dlls/UnityEngine.CoreModule.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="UnityEngine.PhysicsModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
<Reference Include="UnityEngine.PhysicsModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||||
<HintPath>dlls\UnityEngine.PhysicsModule.dll</HintPath>
|
<HintPath>dlls/UnityEngine.PhysicsModule.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="UnityEngine.TextCoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
<Reference Include="UnityEngine.TextCoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||||
<HintPath>dlls\UnityEngine.TextCoreModule.dll</HintPath>
|
<HintPath>dlls/UnityEngine.TextCoreModule.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="UnityEngine.TextRenderingModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
<Reference Include="UnityEngine.TextRenderingModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||||
<HintPath>dlls\UnityEngine.TextRenderingModule.dll</HintPath>
|
<HintPath>dlls/UnityEngine.TextRenderingModule.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
|
<Reference Include="UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||||
<HintPath>dlls\UnityEngine.UI.dll</HintPath>
|
<HintPath>dlls/UnityEngine.UI.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="UnityEngine.UIElementsModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
<Reference Include="UnityEngine.UIElementsModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||||
<HintPath>dlls\UnityEngine.UIElementsModule.dll</HintPath>
|
<HintPath>dlls/UnityEngine.UIElementsModule.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="UnityEngine.UIModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
<Reference Include="UnityEngine.UIModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||||
<HintPath>dlls\UnityEngine.UIModule.dll</HintPath>
|
<HintPath>dlls/UnityEngine.UIModule.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="DecalConfig.cs" />
|
<Compile Include="DecalConfig.cs" />
|
||||||
<Compile Include="DecalIconFixer.cs" />
|
<Compile Include="DecalIconFixer.cs" />
|
||||||
<Compile Include="DecalPropertyIDs.cs" />
|
<Compile Include="DecalPropertyIDs.cs" />
|
||||||
<Compile Include="MaterialProperties\MaterialColorProperty.cs" />
|
<Compile Include="MaterialProperties/MaterialColorProperty.cs" />
|
||||||
<Compile Include="MaterialProperties\MaterialFloatProperty.cs" />
|
<Compile Include="MaterialProperties/MaterialFloatProperty.cs" />
|
||||||
<Compile Include="MaterialProperties\MaterialKeywordProperty.cs" />
|
<Compile Include="MaterialProperties/MaterialKeywordProperty.cs" />
|
||||||
<Compile Include="MaterialProperties\MaterialProperty.cs" />
|
<Compile Include="MaterialProperties/MaterialProperty.cs" />
|
||||||
<Compile Include="MaterialProperties\MaterialPropertyCollection.cs" />
|
<Compile Include="MaterialProperties/MaterialPropertyCollection.cs" />
|
||||||
<Compile Include="MaterialProperties\MaterialTextureProperty.cs" />
|
<Compile Include="MaterialProperties/MaterialTextureProperty.cs" />
|
||||||
<Compile Include="ModuleConformalFlag.cs" />
|
<Compile Include="ModuleConformalFlag.cs" />
|
||||||
<Compile Include="ModuleConformalText.cs" />
|
<Compile Include="ModuleConformalText.cs" />
|
||||||
<Compile Include="ProjectionTarget.cs" />
|
<Compile Include="ProjectionTarget.cs" />
|
||||||
<Compile Include="ModuleConformalDecal.cs" />
|
<Compile Include="ModuleConformalDecal.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties/AssemblyInfo.cs" />
|
||||||
<Compile Include="Text\DecalFont.cs" />
|
<Compile Include="Text/DecalFont.cs" />
|
||||||
<Compile Include="Text\FontLoader.cs" />
|
<Compile Include="Text/FontLoader.cs" />
|
||||||
<Compile Include="Text\TextRenderer.cs" />
|
<Compile Include="Text/TextRenderer.cs" />
|
||||||
<Compile Include="Text\DecalText.cs" />
|
<Compile Include="Text/DecalText.cs" />
|
||||||
<Compile Include="Test\TestLayers.cs" />
|
<Compile Include="Test/TestLayers.cs" />
|
||||||
<Compile Include="UI\FontMenuController.cs" />
|
<Compile Include="UI/ColorPickerController.cs" />
|
||||||
<Compile Include="UI\FontMenuItem.cs" />
|
<Compile Include="UI/FontMenuController.cs" />
|
||||||
<Compile Include="UI\TextEntryController.cs" />
|
<Compile Include="UI/FontMenuItem.cs" />
|
||||||
<Compile Include="UI\UILoader.cs" />
|
<Compile Include="UI/TextEntryController.cs" />
|
||||||
<Compile Include="UI\UITag.cs" />
|
<Compile Include="UI/UILoader.cs" />
|
||||||
|
<Compile Include="UI/UITag.cs" />
|
||||||
|
<Compile Include="UI\ColorBoxSlider.cs" />
|
||||||
|
<Compile Include="UI\ColorChannelSlider.cs" />
|
||||||
|
<Compile Include="Util/Logging.cs" />
|
||||||
|
<Compile Include="Util/OrientedBounds.cs" />
|
||||||
|
<Compile Include="Util/TextureUtils.cs" />
|
||||||
|
<Compile Include="Util/ParseUtil.cs" />
|
||||||
|
<Compile Include="UI/BoxSlider.cs" />
|
||||||
<Compile Include="Util\ColorHSL.cs" />
|
<Compile Include="Util\ColorHSL.cs" />
|
||||||
<Compile Include="Util\Logging.cs" />
|
|
||||||
<Compile Include="Util\OrientedBounds.cs" />
|
|
||||||
<Compile Include="Util\TextureUtils.cs" />
|
|
||||||
<Compile Include="Util\ParseUtil.cs" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)/Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent>sh -e -c "cp -v '$(TargetPath)' '$(SolutionDir)/../GameData/ConformalDecals/Plugins'"</PostBuildEvent>
|
<PostBuildEvent>sh -e -c "cp -v '$(TargetPath)' '$(SolutionDir)/../GameData/ConformalDecals/Plugins'"</PostBuildEvent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -26,7 +26,6 @@ namespace ConformalDecals.UI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Vector2 Value {
|
public Vector2 Value {
|
||||||
get => _value;
|
get => _value;
|
||||||
set {
|
set {
|
||||||
|
55
Source/ConformalDecals/UI/ColorBoxSlider.cs
Normal file
55
Source/ConformalDecals/UI/ColorBoxSlider.cs
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
81
Source/ConformalDecals/UI/ColorChannelSlider.cs
Normal file
81
Source/ConformalDecals/UI/ColorChannelSlider.cs
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
92
Source/ConformalDecals/UI/ColorPickerController.cs
Normal file
92
Source/ConformalDecals/UI/ColorPickerController.cs
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,27 +3,30 @@ using System.Collections.Generic;
|
|||||||
using ConformalDecals.Text;
|
using ConformalDecals.Text;
|
||||||
using UniLinq;
|
using UniLinq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.Events;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
||||||
namespace ConformalDecals.UI {
|
namespace ConformalDecals.UI {
|
||||||
public class FontMenuController : MonoBehaviour {
|
public class FontMenuController : MonoBehaviour {
|
||||||
|
[Serializable]
|
||||||
|
public class FontUpdateEvent : UnityEvent<DecalFont> { }
|
||||||
|
|
||||||
|
[SerializeField] private FontUpdateEvent _onFontChanged = new FontUpdateEvent();
|
||||||
|
|
||||||
[SerializeField] private GameObject _menuItem;
|
[SerializeField] private GameObject _menuItem;
|
||||||
[SerializeField] private GameObject _menuList;
|
[SerializeField] private GameObject _menuList;
|
||||||
|
|
||||||
public DecalFont currentFont;
|
private DecalFont _currentFont;
|
||||||
|
|
||||||
public delegate void FontUpdateReceiver(DecalFont font);
|
public static FontMenuController Create(IEnumerable<DecalFont> fonts, DecalFont currentFont, UnityAction<DecalFont> fontUpdateCallback) {
|
||||||
|
|
||||||
public FontUpdateReceiver fontUpdateCallback;
|
|
||||||
|
|
||||||
public static FontMenuController Create(IEnumerable<DecalFont> fonts, DecalFont currentFont, FontUpdateReceiver fontUpdateCallback) {
|
|
||||||
var menu = Instantiate(UILoader.FontMenuPrefab, MainCanvasUtil.MainCanvas.transform, true);
|
var menu = Instantiate(UILoader.FontMenuPrefab, MainCanvasUtil.MainCanvas.transform, true);
|
||||||
menu.AddComponent<DragPanel>();
|
menu.AddComponent<DragPanel>();
|
||||||
MenuNavigation.SpawnMenuNavigation(menu, Navigation.Mode.Automatic, true);
|
MenuNavigation.SpawnMenuNavigation(menu, Navigation.Mode.Automatic, true);
|
||||||
|
|
||||||
var controller = menu.GetComponent<FontMenuController>();
|
var controller = menu.GetComponent<FontMenuController>();
|
||||||
controller.fontUpdateCallback = fontUpdateCallback;
|
controller._currentFont = currentFont;
|
||||||
controller.currentFont = currentFont;
|
controller._onFontChanged.AddListener(fontUpdateCallback);
|
||||||
|
|
||||||
controller.Populate(fonts);
|
controller.Populate(fonts);
|
||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
@ -33,8 +36,8 @@ namespace ConformalDecals.UI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void OnFontSelected(DecalFont font) {
|
public void OnFontSelected(DecalFont font) {
|
||||||
currentFont = font ?? throw new ArgumentNullException(nameof(font));
|
_currentFont = font ?? throw new ArgumentNullException(nameof(font));
|
||||||
fontUpdateCallback(currentFont);
|
_onFontChanged.Invoke(_currentFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Populate(IEnumerable<DecalFont> fonts) {
|
public void Populate(IEnumerable<DecalFont> fonts) {
|
||||||
@ -52,7 +55,7 @@ namespace ConformalDecals.UI {
|
|||||||
fontItem.Font = font;
|
fontItem.Font = font;
|
||||||
fontItem.fontSelectionCallback = OnFontSelected;
|
fontItem.fontSelectionCallback = OnFontSelected;
|
||||||
|
|
||||||
if (font == currentFont) active = fontItem.toggle;
|
if (font == _currentFont) active = fontItem.toggle;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (active != null) active.isOn = true;
|
if (active != null) active.isOn = true;
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
|
using System;
|
||||||
using ConformalDecals.Text;
|
using ConformalDecals.Text;
|
||||||
using TMPro;
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.Events;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
||||||
namespace ConformalDecals.UI {
|
namespace ConformalDecals.UI {
|
||||||
public class TextEntryController : MonoBehaviour {
|
public class TextEntryController : MonoBehaviour {
|
||||||
public delegate void TextUpdateReceiver(DecalText text);
|
[Serializable]
|
||||||
|
public class TextUpdateEvent : UnityEvent<DecalText> { }
|
||||||
|
|
||||||
public TextUpdateReceiver textUpdateCallback;
|
[SerializeField] private TextUpdateEvent _onTextUpdate = new TextUpdateEvent();
|
||||||
|
|
||||||
public DecalText decalText;
|
private DecalText _decalText;
|
||||||
private FontMenuController _fontMenu;
|
private FontMenuController _fontMenu;
|
||||||
|
|
||||||
[SerializeField] private Selectable _textBox;
|
[SerializeField] private Selectable _textBox;
|
||||||
@ -22,28 +25,28 @@ namespace ConformalDecals.UI {
|
|||||||
[SerializeField] private Toggle _smallCapsButton;
|
[SerializeField] private Toggle _smallCapsButton;
|
||||||
[SerializeField] private Toggle _verticalButton;
|
[SerializeField] private Toggle _verticalButton;
|
||||||
|
|
||||||
public static TextEntryController Create(DecalText text, TextUpdateReceiver textUpdateCallback) {
|
public static TextEntryController Create(DecalText text, UnityAction<DecalText> textUpdateCallback) {
|
||||||
var window = Instantiate(UILoader.TextEntryPrefab, MainCanvasUtil.MainCanvas.transform, true);
|
var window = Instantiate(UILoader.TextEntryPrefab, MainCanvasUtil.MainCanvas.transform, true);
|
||||||
window.AddComponent<DragPanel>();
|
window.AddComponent<DragPanel>();
|
||||||
MenuNavigation.SpawnMenuNavigation(window, Navigation.Mode.Automatic, true);
|
MenuNavigation.SpawnMenuNavigation(window, Navigation.Mode.Automatic, true);
|
||||||
|
|
||||||
var controller = window.GetComponent<TextEntryController>();
|
var controller = window.GetComponent<TextEntryController>();
|
||||||
controller.decalText = text;
|
controller._decalText = text;
|
||||||
controller.textUpdateCallback = textUpdateCallback;
|
controller._onTextUpdate.AddListener(textUpdateCallback);
|
||||||
text.font.SetupSample(controller._fontButton.GetComponentInChildren<TextMeshProUGUI>());
|
text.font.SetupSample(controller._fontButton.GetComponentInChildren<TextMeshProUGUI>());
|
||||||
|
|
||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Start() {
|
private void Start() {
|
||||||
((TMP_InputField) _textBox).text = decalText.text;
|
((TMP_InputField) _textBox).text = _decalText.text;
|
||||||
|
|
||||||
_outlineWidthSlider.value = decalText.outlineWidth;
|
_outlineWidthSlider.value = _decalText.outlineWidth;
|
||||||
_boldButton.isOn = (decalText.style & FontStyles.Bold) != 0;
|
_boldButton.isOn = (_decalText.style & FontStyles.Bold) != 0;
|
||||||
_italicButton.isOn = (decalText.style & FontStyles.Italic) != 0;
|
_italicButton.isOn = (_decalText.style & FontStyles.Italic) != 0;
|
||||||
_underlineButton.isOn = (decalText.style & FontStyles.Underline) != 0;
|
_underlineButton.isOn = (_decalText.style & FontStyles.Underline) != 0;
|
||||||
_smallCapsButton.isOn = (decalText.style & FontStyles.SmallCaps) != 0;
|
_smallCapsButton.isOn = (_decalText.style & FontStyles.SmallCaps) != 0;
|
||||||
_verticalButton.isOn = decalText.vertical;
|
_verticalButton.isOn = _decalText.vertical;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,26 +56,26 @@ namespace ConformalDecals.UI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void OnAnyUpdate() {
|
public void OnAnyUpdate() {
|
||||||
textUpdateCallback(decalText);
|
_onTextUpdate.Invoke(_decalText);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnTextUpdate(string newText) {
|
public void OnTextUpdate(string newText) {
|
||||||
this.decalText.text = newText;
|
this._decalText.text = newText;
|
||||||
|
|
||||||
OnAnyUpdate();
|
OnAnyUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnFontMenu() {
|
public void OnFontMenu() {
|
||||||
if (_fontMenu == null) _fontMenu = FontMenuController.Create(DecalConfig.Fonts, decalText.font, OnFontUpdate);
|
if (_fontMenu == null) _fontMenu = FontMenuController.Create(DecalConfig.Fonts, _decalText.font, OnFontUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnFontUpdate(DecalFont font) {
|
public void OnFontUpdate(DecalFont font) {
|
||||||
decalText.font = font;
|
_decalText.font = font;
|
||||||
font.SetupSample(_fontButton.GetComponentInChildren<TextMeshProUGUI>());
|
font.SetupSample(_fontButton.GetComponentInChildren<TextMeshProUGUI>());
|
||||||
|
|
||||||
var textBox = ((TMP_InputField) _textBox);
|
var textBox = ((TMP_InputField) _textBox);
|
||||||
textBox.textComponent.fontStyle = decalText.style | decalText.font.fontStyle;
|
textBox.textComponent.fontStyle = _decalText.style | _decalText.font.fontStyle;
|
||||||
textBox.fontAsset = decalText.font.fontAsset;
|
textBox.fontAsset = _decalText.font.fontAsset;
|
||||||
|
|
||||||
OnAnyUpdate();
|
OnAnyUpdate();
|
||||||
}
|
}
|
||||||
@ -80,64 +83,64 @@ namespace ConformalDecals.UI {
|
|||||||
public void OnColorMenu() { }
|
public void OnColorMenu() { }
|
||||||
|
|
||||||
public void OnColorUpdate(Color color) {
|
public void OnColorUpdate(Color color) {
|
||||||
decalText.color = color;
|
_decalText.color = color;
|
||||||
OnAnyUpdate();
|
OnAnyUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnOutlineColorMenu() { }
|
public void OnOutlineColorMenu() { }
|
||||||
|
|
||||||
public void OnOutlineColorUpdate(Color color) {
|
public void OnOutlineColorUpdate(Color color) {
|
||||||
decalText.outlineColor = color;
|
_decalText.outlineColor = color;
|
||||||
OnAnyUpdate();
|
OnAnyUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnOutlineUpdate(float value) {
|
public void OnOutlineUpdate(float value) {
|
||||||
decalText.outlineWidth = value;
|
_decalText.outlineWidth = value;
|
||||||
OnAnyUpdate();
|
OnAnyUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnBoldUpdate(bool state) {
|
public void OnBoldUpdate(bool state) {
|
||||||
if (state) decalText.style |= FontStyles.Bold;
|
if (state) _decalText.style |= FontStyles.Bold;
|
||||||
else decalText.style &= ~FontStyles.Bold;
|
else _decalText.style &= ~FontStyles.Bold;
|
||||||
|
|
||||||
((TMP_InputField) _textBox).textComponent.fontStyle = decalText.style | decalText.font.fontStyle;
|
((TMP_InputField) _textBox).textComponent.fontStyle = _decalText.style | _decalText.font.fontStyle;
|
||||||
|
|
||||||
OnAnyUpdate();
|
OnAnyUpdate();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnItalicUpdate(bool state) {
|
public void OnItalicUpdate(bool state) {
|
||||||
if (state) decalText.style |= FontStyles.Italic;
|
if (state) _decalText.style |= FontStyles.Italic;
|
||||||
else decalText.style &= ~FontStyles.Italic;
|
else _decalText.style &= ~FontStyles.Italic;
|
||||||
|
|
||||||
((TMP_InputField) _textBox).textComponent.fontStyle = decalText.style | decalText.font.fontStyle;
|
((TMP_InputField) _textBox).textComponent.fontStyle = _decalText.style | _decalText.font.fontStyle;
|
||||||
|
|
||||||
OnAnyUpdate();
|
OnAnyUpdate();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnUnderlineUpdate(bool state) {
|
public void OnUnderlineUpdate(bool state) {
|
||||||
if (state) decalText.style |= FontStyles.Underline;
|
if (state) _decalText.style |= FontStyles.Underline;
|
||||||
else decalText.style &= ~FontStyles.Underline;
|
else _decalText.style &= ~FontStyles.Underline;
|
||||||
|
|
||||||
((TMP_InputField) _textBox).textComponent.fontStyle = decalText.style | decalText.font.fontStyle;
|
((TMP_InputField) _textBox).textComponent.fontStyle = _decalText.style | _decalText.font.fontStyle;
|
||||||
|
|
||||||
OnAnyUpdate();
|
OnAnyUpdate();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnSmallCapsUpdate(bool state) {
|
public void OnSmallCapsUpdate(bool state) {
|
||||||
if (state) decalText.style |= FontStyles.SmallCaps;
|
if (state) _decalText.style |= FontStyles.SmallCaps;
|
||||||
else decalText.style &= ~FontStyles.SmallCaps;
|
else _decalText.style &= ~FontStyles.SmallCaps;
|
||||||
|
|
||||||
((TMP_InputField) _textBox).textComponent.fontStyle = decalText.style | decalText.font.fontStyle;
|
((TMP_InputField) _textBox).textComponent.fontStyle = _decalText.style | _decalText.font.fontStyle;
|
||||||
|
|
||||||
OnAnyUpdate();
|
OnAnyUpdate();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnVerticalUpdate(bool state) {
|
public void OnVerticalUpdate(bool state) {
|
||||||
decalText.vertical = state;
|
_decalText.vertical = state;
|
||||||
OnAnyUpdate();
|
OnAnyUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,18 +10,22 @@ namespace ConformalDecals.UI {
|
|||||||
|
|
||||||
private static GameObject _textEntryPrefab;
|
private static GameObject _textEntryPrefab;
|
||||||
private static GameObject _fontMenuPrefab;
|
private static GameObject _fontMenuPrefab;
|
||||||
|
private static GameObject _colorPickerPrefab;
|
||||||
|
|
||||||
public static GameObject FontMenuPrefab => _fontMenuPrefab;
|
public static GameObject FontMenuPrefab => _fontMenuPrefab;
|
||||||
public static GameObject TextEntryPrefab => _textEntryPrefab;
|
public static GameObject TextEntryPrefab => _textEntryPrefab;
|
||||||
|
public static GameObject ColorPickerPrefab => _colorPickerPrefab;
|
||||||
|
|
||||||
private void Awake() {
|
private void Awake() {
|
||||||
var prefabs = AssetBundle.LoadFromFile(Path + "ui.conformaldecals");
|
var prefabs = AssetBundle.LoadFromFile(Path + "ui.conformaldecals");
|
||||||
|
|
||||||
_textEntryPrefab = prefabs.LoadAsset("TextEntryPanel") as GameObject;
|
_textEntryPrefab = prefabs.LoadAsset("TextEntryPanel") as GameObject;
|
||||||
_fontMenuPrefab = prefabs.LoadAsset("FontMenuPanel") as GameObject;
|
_fontMenuPrefab = prefabs.LoadAsset("FontMenuPanel") as GameObject;
|
||||||
|
_colorPickerPrefab = prefabs.LoadAsset("ColorPickerPanel") as GameObject;
|
||||||
|
|
||||||
ProcessWindow(_textEntryPrefab);
|
ProcessWindow(_textEntryPrefab);
|
||||||
ProcessWindow(_fontMenuPrefab);
|
ProcessWindow(_fontMenuPrefab);
|
||||||
|
ProcessWindow(_colorPickerPrefab);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessWindow(GameObject window) {
|
private static void ProcessWindow(GameObject window) {
|
||||||
|
@ -17,7 +17,7 @@ namespace ConformalDecals.Util {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return $"HSLA({(object) this.h:F3}, {(object) this.s:F3}, {(object) this.l:F3}, {(object) this.a:F3})";
|
return $"HSLA({this.h:F3}, {this.s:F3}, {this.l:F3}, {this.a:F3})";
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ToString(string format) {
|
public string ToString(string format) {
|
||||||
@ -49,6 +49,41 @@ namespace ConformalDecals.Util {
|
|||||||
return ((Vector4) this).GetHashCode();
|
return ((Vector4) this).GetHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float this[int index] {
|
||||||
|
get {
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
return this.h;
|
||||||
|
case 1:
|
||||||
|
return this.s;
|
||||||
|
case 2:
|
||||||
|
return this.l;
|
||||||
|
case 3:
|
||||||
|
return this.a;
|
||||||
|
default:
|
||||||
|
throw new IndexOutOfRangeException("Invalid Vector3 index!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
this.h = value;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
this.s = value;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this.l = value;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this.a = value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IndexOutOfRangeException("Invalid Vector3 index!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static bool operator ==(ColorHSL lhs, ColorHSL rhs) {
|
public static bool operator ==(ColorHSL lhs, ColorHSL rhs) {
|
||||||
return lhs.Equals(rhs);
|
return lhs.Equals(rhs);
|
||||||
}
|
}
|
||||||
|
@ -139,16 +139,12 @@ namespace ConformalDecals.Util {
|
|||||||
throw new FormatException($"Improperly formatted {typeof(T)} value for {valueName} : '{valueString}");
|
throw new FormatException($"Improperly formatted {typeof(T)} value for {valueName} : '{valueString}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool TryParseColor32(string valueString, out Color32 value) {
|
public static bool TryParseHexColor(string valueString, out Color32 value) {
|
||||||
value = new Color32(0, 0, 0, byte.MaxValue);
|
value = new Color32(0, 0, 0, byte.MaxValue);
|
||||||
|
|
||||||
// HTML-style hex color
|
if (!int.TryParse(valueString, System.Globalization.NumberStyles.HexNumber, null, out var hexColor)) return false;
|
||||||
if (valueString[0] == '#') {
|
|
||||||
var hexColorString = valueString.Substring(1);
|
|
||||||
|
|
||||||
if (!int.TryParse(hexColorString, System.Globalization.NumberStyles.HexNumber, null, out var hexColor)) return false;
|
switch (valueString.Length) {
|
||||||
|
|
||||||
switch (hexColorString.Length) {
|
|
||||||
case 8: // RRGGBBAA
|
case 8: // RRGGBBAA
|
||||||
value.a = (byte) (hexColor & 0xFF);
|
value.a = (byte) (hexColor & 0xFF);
|
||||||
hexColor >>= 8;
|
hexColor >>= 8;
|
||||||
@ -180,6 +176,19 @@ namespace ConformalDecals.Util {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool TryParseColor32(string valueString, out Color32 value) {
|
||||||
|
value = new Color32(0, 0, 0, byte.MaxValue);
|
||||||
|
|
||||||
|
// hex color
|
||||||
|
if (valueString[0] == '#') {
|
||||||
|
var hexColorString = valueString.Substring(1);
|
||||||
|
|
||||||
|
if (TryParseHexColor(hexColorString, out var hexColor)) {
|
||||||
|
value = hexColor;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// named color
|
// named color
|
||||||
if (NamedColors.TryGetValue(valueString, out var namedColor)) {
|
if (NamedColors.TryGetValue(valueString, out var namedColor)) {
|
||||||
value = namedColor;
|
value = namedColor;
|
||||||
|
Loading…
Reference in New Issue
Block a user