Skip to content
This repository has been archived by the owner on Nov 6, 2022. It is now read-only.

Commit

Permalink
Palette color editor
Browse files Browse the repository at this point in the history
Reorganizing the palette classes into a new folder
Fixed some potential issues with nullable enum fields in xmls
  • Loading branch information
klyte45 committed Apr 25, 2021
1 parent 97e16fa commit b735a48
Show file tree
Hide file tree
Showing 15 changed files with 411 additions and 279 deletions.
4 changes: 3 additions & 1 deletion CommonsWindow/List/Components/UVMLineListItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ private void AwakeLineFormat()
m_lineNumberFormatted = m_lineColor.GetComponentInChildren<UIButton>();
m_lineNumberFormatted.textScale = 1.5f;
m_lineNumberFormatted.useOutline = true;

m_lineColor.relativePosition = new Vector3(90, 0);
}
private void AwakeShowLineButton()
{
Expand Down Expand Up @@ -343,7 +345,7 @@ private void AwakeLabels()
m_lineBalance.transform.SetParent(m_lineStops.transform.parent);
m_lineBalance.name = "LineExpenses";
m_lineBalance.minimumSize = new Vector2(145, 18);
KlyteMonoUtils.LimitWidthAndBox(m_lineBalance,out UIPanel containerLineBalance);
KlyteMonoUtils.LimitWidthAndBox(m_lineBalance, out UIPanel containerLineBalance);

containerLineBalance.relativePosition = new Vector3(625, 10);
containerPassenger.relativePosition = new Vector3(540, 10);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Klyte.TransportLinesManager.Xml
public class TLMAutoNameConfigurationData<E> : IIdentifiable, ITLMAutoNameConfigurable where E : struct, Enum
{
[XmlAttribute("refName")]
public E? Index { get; set; }
public E Index { get; set; }

[XmlAttribute("useInAutoname")]
public bool UseInAutoName { get; set; }
Expand All @@ -19,7 +19,7 @@ public class TLMAutoNameConfigurationData<E> : IIdentifiable, ITLMAutoNameConfig
[XmlIgnore]
public long? Id
{
get => Index is null ? null : (long?)Convert.ToInt32(Index); set => Index = Enum.GetValues(typeof(E)).OfType<E?>().Where(x => Convert.ToInt32(x) == value).FirstOrDefault();
get => (long?)Convert.ToInt32(Index); set => Index = Enum.GetValues(typeof(E)).OfType<E>().Where(x => Convert.ToInt32(x) == value).FirstOrDefault();
}
}

Expand Down
6 changes: 3 additions & 3 deletions OptionsMenu/TLMShowConfigTab.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@ private void Awake()
TSD.GetConfig().NonPrefixedNaming = TLMConfigOptions.namingOptionsSuffix[x];
}
});
AddDropdown(Locale.Get("K45_TLM_PALETTE"), out m_paletteDD, m_uiHelper, TLMAutoColorPalettes.paletteList, (x) =>
AddDropdown(Locale.Get("K45_TLM_PALETTE"), out m_paletteDD, m_uiHelper, TLMAutoColorPaletteContainer.PaletteList, (x) =>
{
if (x >= 0)
{
TSD.GetConfig().Palette = x == 0 ? null : TLMAutoColorPalettes.paletteList[x];
TSD.GetConfig().Palette = x == 0 ? null : TLMAutoColorPaletteContainer.PaletteList[x];
}
});
AddDropdown(Locale.Get("K45_TLM_ICON"), out m_iconDD, m_uiHelper, Enum.GetValues(typeof(LineIconSpriteNames)).OfType<LineIconSpriteNames>().Select(x => x.GetNameForTLM()).ToArray(), (x) =>
Expand Down Expand Up @@ -158,7 +158,7 @@ private void OnSuffixOptionChange()
public void ReloadData()
{
var config = TSD.GetConfig();
m_paletteDD.selectedValue = config.Palette.TrimToNull() ?? TLMAutoColorPalettes.paletteList[0];
m_paletteDD.selectedValue = config.Palette.TrimToNull() ?? TLMAutoColorPaletteContainer.PaletteList[0];
m_iconDD.selectedIndex = (int)config.DefaultLineIcon;
m_suffixDD.selectedIndex = Array.IndexOf(TLMConfigOptions.namingOptionsSuffix, config.Suffix);
m_nonPrefixDD.selectedIndex = Array.IndexOf(TLMConfigOptions.namingOptionsSuffix, config.NonPrefixedNaming);
Expand Down
214 changes: 197 additions & 17 deletions OptionsMenu/Tabs/TLMPaletteOptionsTab.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,36 @@
using ColossalFramework.Globalization;
using ColossalFramework;
using ColossalFramework.Globalization;
using ColossalFramework.UI;
using Klyte.Commons.Extensions;
using Klyte.Commons.UI.Sprites;
using Klyte.Commons.UI;
using Klyte.Commons.UI.SpriteNames;
using Klyte.Commons.Utils;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;

namespace Klyte.TransportLinesManager.OptionsMenu.Tabs
{
internal class TLMPaletteOptionsTab : UICustomControl, ITLMConfigOptionsTab
{
private const string COLOR_SELECTOR_TEMPLATE = "K45_TLM_PaletteColorListSelectorTemplate";

private UIComponent parent;
private UIDropDown m_paletteSelect;
private UITemplateList<UIPanel> m_colorFieldTemplateListColors;
private UIButton m_addColor;
private UIScrollablePanel m_colorListScroll;
private bool canEdit;

public static event OnPalettesChanged onPaletteReloaded;
public static event OnPalettesChanged OnPaletteReloaded;

public void ReloadData()
{
string idxSel = m_paletteSelect.selectedValue;
m_paletteSelect.items = TLMAutoColorPalettes.paletteListForEditing;
m_paletteSelect.items = TLMAutoColorPaletteContainer.PaletteListForEditing;
m_paletteSelect.selectedValue = idxSel;

}

private void Awake()
Expand All @@ -44,32 +53,203 @@ private void Awake()
namesFilesButton.text = fiPalette.FullName + Path.DirectorySeparatorChar;
((UIButton)group6.AddButton(Locale.Get("K45_TLM_RELOAD_PALETTES"), delegate ()
{
TLMAutoColorPalettes.Reload();
TLMAutoColorPaletteContainer.Reload();
ReloadData();
onPaletteReloaded?.Invoke();
OnPaletteReloaded?.Invoke();
})).width = 710;

NumberedColorList colorList = null;
m_paletteSelect = group6.AddDropdown(Locale.Get("K45_TLM_PALETTE_VIEW"), TLMAutoColorPalettes.paletteListForEditing, 0, delegate (int sel)
UIPanel m_listColorContainer = null;
m_paletteSelect = group6.AddDropdown(Locale.Get("K45_TLM_PALETTE_VIEW"), TLMAutoColorPaletteContainer.PaletteListForEditing, 0, delegate (int sel)
{
if (sel <= 0 || sel >= TLMAutoColorPalettes.paletteListForEditing.Length)
if (sel <= 0 || sel >= TLMAutoColorPaletteContainer.PaletteListForEditing.Length)
{
colorList.Disable();
m_listColorContainer?.Disable();
m_colorFieldTemplateListColors?.SetItemCount(0);
}
else
{
colorList.ColorList = TLMAutoColorPalettes.getColors(TLMAutoColorPalettes.paletteListForEditing[sel]);
colorList.Enable();
m_listColorContainer?.Enable();
UpdateColorList(TLMAutoColorPaletteContainer.GetColors(TLMAutoColorPaletteContainer.PaletteListForEditing[sel]));
}
}) as UIDropDown;
m_paletteSelect.GetComponentInParent<UIPanel>().width = 710;
m_paletteSelect.GetComponentInParent<UIPanel>().width = 720;
m_paletteSelect.GetComponentInParent<UIPanel>().autoLayoutDirection = LayoutDirection.Horizontal;
m_paletteSelect.GetComponentInParent<UIPanel>().wrapLayout = true;
m_paletteSelect.width = 710;

colorList = group6.AddNumberedColorList(null, new List<Color32>(), (c) => { }, null, null);
colorList.m_spriteName = KlyteResourceLoader.GetDefaultSpriteNameFor(LineIconSpriteNames.K45_SquareIcon, true);
colorList.Size = new Vector2(750, colorList.Size.y);
KlyteMonoUtils.CreateUIElement(out m_listColorContainer, group6.Self.transform, "listColors", new UnityEngine.Vector4(0, 0, group6.Self.width, group6.Self.height - 250));
KlyteMonoUtils.CreateScrollPanel(m_listColorContainer, out m_colorListScroll, out _, m_listColorContainer.width - 20, m_listColorContainer.height);
m_colorListScroll.backgroundSprite = "OptionsScrollbarTrack";
m_colorListScroll.autoLayout = true;
m_colorListScroll.autoLayoutDirection = LayoutDirection.Horizontal;
m_colorListScroll.wrapLayout = true;
}
public void Start()
{
CreateTemplateColorItem();
m_colorFieldTemplateListColors = new UITemplateList<UIPanel>(m_colorListScroll, COLOR_SELECTOR_TEMPLATE);
if (canEdit)
{
KlyteMonoUtils.InitCircledButton(m_colorListScroll, out m_addColor, CommonsSpriteNames.K45_Plus, (x, y) => AddColor(), "", 36);
DefaultEditorUILib.AddButtonInEditorRow(m_paletteSelect, CommonsSpriteNames.K45_Plus, () => AddPalette(), "K45_TLM_ADDPALETTE", true, (int)m_paletteSelect.height);
}
}

private void AddPalette(string errorMsg = null, string oldVal = null) => K45DialogControl.ShowModalPromptText(new K45DialogControl.BindProperties
{
title = Locale.Get("K45_TLM_ADDPALETTE"),
message = (errorMsg + "\n").TrimToNull() + Locale.Get("K45_TLM_ADDPALETTE_PROMPTNAME"),
defaultTextFieldContent = oldVal,
showButton1 = true,
textButton1 = Locale.Get("EXCEPTION_OK"),
textButton2 = Locale.Get("CANCEL"),
showButton2 = true
}, (x, val) =>
{
if (x == 1)
{
if (val == TLMAutoColorPaletteContainer.PALETTE_RANDOM || !(TLMAutoColorPaletteContainer.GetPalette(val) is null))
{
AddPalette(Locale.Get("K45_TLM_ADDPALETTE_ERROR_PALETTEALREADYEXISTS"), val);
}
else if (val.IsNullOrWhiteSpace())
{
AddPalette(Locale.Get("K45_TLM_ADDPALETTE_ERROR_INVALIDNAME"), val);
}
TLMAutoColorPaletteContainer.AddPalette(val);
TLMAutoColorPaletteContainer.Save(val);
ReloadData();
m_paletteSelect.selectedValue = val;
}
return true;
});

private void CreateTemplateColorItem()
{
if (UITemplateUtils.GetTemplateDict().ContainsKey(COLOR_SELECTOR_TEMPLATE))
{
UITemplateUtils.GetTemplateDict().Remove(COLOR_SELECTOR_TEMPLATE);
}
var go = new GameObject();
UIPanel panel = go.AddComponent<UIPanel>();
panel.size = new Vector2(36, 36);
panel.autoLayout = true;
panel.wrapLayout = false;
panel.padding = new RectOffset(4, 4, 4, 4);
panel.autoLayoutDirection = LayoutDirection.Horizontal;

canEdit = KlyteMonoUtils.EnsureColorFieldTemplate();

KlyteMonoUtils.CreateUIElement(out UIColorField colorField, panel.transform);
KlyteMonoUtils.InitColorField(colorField, 36);
var triggerButton = UIHelperExtension.AddLabel(colorField, "0", 36);
triggerButton.autoSize = false;
triggerButton.size = colorField.size;
triggerButton.backgroundSprite = "ColorPickerOutline";
triggerButton.outlineColor = Color.black;
triggerButton.outlineSize = 1;
triggerButton.textScale = 1;
triggerButton.textAlignment = UIHorizontalAlignment.Center;
triggerButton.verticalAlignment = UIVerticalAlignment.Middle;
colorField.triggerButton = triggerButton;
triggerButton.size = colorField.size;
triggerButton.relativePosition = default;
colorField.normalFgSprite = "ColorPickerColor";
colorField.pickerPosition = UIColorField.ColorPickerPosition.LeftBelow;

if (!canEdit)
{
triggerButton.Disable();
}

UITemplateUtils.GetTemplateDict()[COLOR_SELECTOR_TEMPLATE] = panel;
}
private void AddColor()
{
if (canEdit && GetPaletteName(out string paletteName))
{
var palette = TLMAutoColorPaletteContainer.GetPalette(paletteName);
palette.Add();
StartCoroutine(SavePalette(paletteName));
}
}

private void UpdateColorList(List<Color32> colors)
{
UIPanel[] colorPickers = m_colorFieldTemplateListColors.SetItemCount(colors.Count);

for (int i = 0; i < colors.Count; i++)
{
UIColorField colorField = colorPickers[i].GetComponentInChildren<UIColorField>();
if (canEdit && colorField.objectUserData == null)
{
colorField.colorPicker = KlyteMonoUtils.GetDefaultPicker();
colorField.eventSelectedColorReleased += (x, y) =>
{
if (GetPaletteName(out string paletteName))
{
var palette = TLMAutoColorPaletteContainer.GetPalette(paletteName);
var selColor = ((UIColorField)x).selectedColor;
palette[x.parent.zOrder] = selColor;
if (selColor == default)
{
((UIColorField)x).isVisible = false;
((UIColorField)x).OnDisable();
}
StartCoroutine(SavePalette(paletteName));
}
};
colorField.eventColorPickerOpen += KlyteMonoUtils.DefaultColorPickerHandler;
colorField.objectUserData = true;
}
(colorField.triggerButton as UILabel).text = $"{i.ToString("0")}";
(colorField.triggerButton as UILabel).textColor = KlyteMonoUtils.ContrastColor(colors[i]);
(colorField.triggerButton as UILabel).disabledTextColor = KlyteMonoUtils.ContrastColor(colors[i]);
colorField.selectedColor = colors[i];
colorField.isVisible = true;
}
if (canEdit)
{
m_addColor.zOrder = 99999999;
}
}

private bool GetPaletteName(out string paletteName)
{
var sel = m_paletteSelect.selectedIndex;
if (sel <= 0 || sel > TLMAutoColorPaletteContainer.PaletteListForEditing.Length)
{
paletteName = null;
return false;
}
paletteName = TLMAutoColorPaletteContainer.PaletteListForEditing[sel];
return true;
}

public delegate void OnPalettesChanged();

private int framesCooldownSave = 0;
private IEnumerator SavePalette(string paletteName)
{
if (!canEdit)
{
yield break;
}

if (framesCooldownSave > 0)
{
framesCooldownSave = 3;
yield break;
}
framesCooldownSave = 3;
do
{
yield return null;
framesCooldownSave--;
} while (framesCooldownSave > 0);

TLMAutoColorPaletteContainer.Save(paletteName);
UpdateColorList(TLMAutoColorPaletteContainer.GetColors(paletteName));
}
}
}
48 changes: 48 additions & 0 deletions Palettes/RandomPastelColorGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Klyte.Commons.Utils;
using UnityEngine;

namespace Klyte.TransportLinesManager
{
public class RandomPastelColorGenerator
{
private readonly System.Random _random;

public RandomPastelColorGenerator()
{
// seed the generator with 2 because
// this gives a good sequence of colors
const int RandomSeed = 2;
_random = new System.Random(RandomSeed);
}


/// <summary>
/// Returns a random pastel color
/// </summary>
/// <returns></returns>
public Color32 GetNext()
{
// to create lighter colours:
// take a random integer between 0 & 128 (rather than between 0 and 255)
// and then add 64 to make the colour lighter
byte[] colorBytes = new byte[3];
colorBytes[0] = (byte)(_random.Next(128) + 64);
colorBytes[1] = (byte)(_random.Next(128) + 64);
colorBytes[2] = (byte)(_random.Next(128) + 64);
Color32 color = new Color32
{

// make the color fully opaque
a = 255,
r = colorBytes[0],
g = colorBytes[1],
b = colorBytes[2]
};
LogUtils.DoLog(color.ToString());

return color;
}
}

}

Loading

0 comments on commit b735a48

Please sign in to comment.