diff --git a/Source/Editor/GUI/Dialogs/ColorPickerDialog.cs b/Source/Editor/GUI/Dialogs/ColorPickerDialog.cs
index f528710cd..ab002505f 100644
--- a/Source/Editor/GUI/Dialogs/ColorPickerDialog.cs
+++ b/Source/Editor/GUI/Dialogs/ColorPickerDialog.cs
@@ -1,10 +1,11 @@
// Copyright (c) Wojciech Figat. All rights reserved.
+using System.Collections.Generic;
using FlaxEditor.GUI.Input;
+using FlaxEditor.GUI.Tabs;
using FlaxEngine;
using FlaxEngine.GUI;
using FlaxEngine.Json;
-using System.Collections.Generic;
namespace FlaxEditor.GUI.Dialogs
{
@@ -25,15 +26,16 @@ namespace FlaxEditor.GUI.Dialogs
///
public class ColorPickerDialog : Dialog, IColorPickerDialog
{
- private const float ButtonsWidth = 60.0f;
private const float PickerMargin = 6.0f;
- private const float EyedropperMargin = 8.0f;
- private const float RGBAMargin = 12.0f;
- private const float HSVMargin = 0.0f;
private const float ChannelsMargin = 4.0f;
private const float ChannelTextWidth = 12.0f;
private const float SavedColorButtonWidth = 20.0f;
private const float SavedColorButtonHeight = 20.0f;
+ private const float TabHeight = 20;
+ private const float ValueBoxesWidth = 100.0f;
+ private const float HSVRGBTextWidth = 15.0f;
+ private const float ColorPreviewHeight = 50.0f;
+ private const int SavedColorsAmount = 10;
private Color _initialValue;
private Color _value;
@@ -45,16 +47,19 @@ namespace FlaxEditor.GUI.Dialogs
private ColorValueBox.ColorPickerClosedEvent _onClosed;
private ColorSelectorWithSliders _cSelector;
+ private Tabs.Tabs _hsvRGBTabs;
+ private Tab _RGBTab;
+ private Panel _rgbPanel;
private FloatValueBox _cRed;
private FloatValueBox _cGreen;
private FloatValueBox _cBlue;
- private FloatValueBox _cAlpha;
+ private Tab _hsvTab;
+ private Panel _hsvPanel;
private FloatValueBox _cHue;
private FloatValueBox _cSaturation;
private FloatValueBox _cValue;
private TextBox _cHex;
- private Button _cCancel;
- private Button _cOK;
+ private FloatValueBox _cAlpha;
private Button _cEyedropper;
private List _savedColors = new List();
@@ -131,90 +136,103 @@ namespace FlaxEditor.GUI.Dialogs
};
_cSelector.ColorChanged += x => SelectedColor = x;
- // Red
- _cRed = new FloatValueBox(0, _cSelector.Right + PickerMargin + RGBAMargin + ChannelTextWidth, PickerMargin, 100, 0, float.MaxValue, 0.001f)
+ _hsvRGBTabs = new Tabs.Tabs
{
- Parent = this
+ Location = new Float2(_cSelector.Right + 30.0f, PickerMargin),
+ TabsTextHorizontalAlignment = TextAlignment.Center,
+ Width = ValueBoxesWidth + HSVRGBTextWidth * 2.0f + ChannelsMargin * 2.0f,
+ Height = (FloatValueBox.DefaultHeight + ChannelsMargin) * 4 + ChannelsMargin,
+ Parent = this,
+ };
+ _hsvRGBTabs.TabsSize = new Float2(_hsvRGBTabs.Width * 0.5f, TabHeight);
+ _hsvRGBTabs.SelectedTabChanged += SelectedTabChanged;
+
+ // RGB Tab
+ _RGBTab = _hsvRGBTabs.AddTab(new Tab("RGB"));
+ _rgbPanel = new Panel(ScrollBars.Vertical)
+ {
+ AnchorPreset = AnchorPresets.StretchAll,
+ Offsets = Margin.Zero,
+ Parent = _RGBTab,
+ };
+
+ // HSV Tab
+ _hsvTab = _hsvRGBTabs.AddTab(new Tab("HSV"));
+ _hsvPanel = new Panel(ScrollBars.Vertical)
+ {
+ AnchorPreset = AnchorPresets.StretchAll,
+ Offsets = Margin.Zero,
+ Parent = _hsvTab,
+ };
+
+ // Red
+ _cRed = new FloatValueBox(0, HSVRGBTextWidth + ChannelsMargin, PickerMargin, ValueBoxesWidth, 0, float.MaxValue, 0.001f)
+ {
+ Parent = _rgbPanel,
};
_cRed.ValueChanged += OnRGBAChanged;
// Green
_cGreen = new FloatValueBox(0, _cRed.X, _cRed.Bottom + ChannelsMargin, _cRed.Width, 0, float.MaxValue, 0.001f)
{
- Parent = this
+ Parent = _rgbPanel,
};
_cGreen.ValueChanged += OnRGBAChanged;
// Blue
_cBlue = new FloatValueBox(0, _cRed.X, _cGreen.Bottom + ChannelsMargin, _cRed.Width, 0, float.MaxValue, 0.001f)
{
- Parent = this
+ Parent = _rgbPanel,
};
_cBlue.ValueChanged += OnRGBAChanged;
- // Alpha
- _cAlpha = new FloatValueBox(0, _cRed.X, _cBlue.Bottom + ChannelsMargin, _cRed.Width, 0, float.MaxValue, 0.001f)
- {
- Parent = this
- };
- _cAlpha.ValueChanged += OnRGBAChanged;
-
// Hue
- _cHue = new FloatValueBox(0, PickerMargin + HSVMargin + ChannelTextWidth, _cSelector.Bottom + PickerMargin, 100)
+ _cHue = new FloatValueBox(0, HSVRGBTextWidth + ChannelsMargin, PickerMargin, ValueBoxesWidth)
{
- Parent = this
+ Parent = _hsvPanel,
+ Category = Utils.ValueCategory.Angle,
};
_cHue.ValueChanged += OnHSVChanged;
// Saturation
_cSaturation = new FloatValueBox(0, _cHue.X, _cHue.Bottom + ChannelsMargin, _cHue.Width, 0, 100.0f, 0.1f)
{
- Parent = this
+ Parent = _hsvPanel,
};
_cSaturation.ValueChanged += OnHSVChanged;
// Value
_cValue = new FloatValueBox(0, _cHue.X, _cSaturation.Bottom + ChannelsMargin, _cHue.Width, 0, float.MaxValue, 0.1f)
{
- Parent = this
+ Parent = _hsvPanel,
};
_cValue.ValueChanged += OnHSVChanged;
- // Set valid dialog size based on UI content
- _dialogSize = Size = new Float2(_cRed.Right + PickerMargin, 300);
+ // Alpha
+ _cAlpha = new FloatValueBox(0, _hsvRGBTabs.Left + HSVRGBTextWidth + ChannelsMargin, _hsvRGBTabs.Bottom + ChannelsMargin * 4.0f, ValueBoxesWidth, 0, float.MaxValue, 0.001f)
+ {
+ Parent = this,
+ };
+ _cAlpha.ValueChanged += OnRGBAChanged;
// Hex
- const float hexTextBoxWidth = 80;
- _cHex = new TextBox(false, Width - hexTextBoxWidth - PickerMargin, _cSelector.Bottom + PickerMargin, hexTextBoxWidth)
+ _cHex = new TextBox(false, _hsvRGBTabs.Left + HSVRGBTextWidth + ChannelsMargin, _cAlpha.Bottom + ChannelsMargin * 2.0f, ValueBoxesWidth)
{
- Parent = this
+ Parent = this,
};
_cHex.EditEnd += OnHexChanged;
- // Cancel
- _cCancel = new Button(Width - ButtonsWidth - PickerMargin, Height - Button.DefaultHeight - PickerMargin, ButtonsWidth)
- {
- Text = "Cancel",
- Parent = this
- };
- _cCancel.Clicked += OnCancel;
-
- // OK
- _cOK = new Button(_cCancel.Left - ButtonsWidth - PickerMargin, _cCancel.Y, ButtonsWidth)
- {
- Text = "Ok",
- Parent = this
- };
- _cOK.Clicked += OnSubmit;
+ // Set valid dialog size based on UI content
+ _dialogSize = Size = new Float2(_hsvRGBTabs.Right + PickerMargin, _cHex.Bottom + 40.0f + ColorPreviewHeight + PickerMargin);
// Create saved color buttons
- CreateAllSaveButtons();
+ CreateAllSavedColorsButtons();
// Eyedropper button
var style = Style.Current;
- _cEyedropper = new Button(_cOK.X - EyedropperMargin, _cHex.Bottom + PickerMargin)
+ _cEyedropper = new Button(_cSelector.BottomLeft.X, _cSelector.BottomLeft.Y - 25.0f, 25.0f, 25.0f)
{
- TooltipText = "Eyedropper tool to pick a color directly from the screen",
+ TooltipText = "Eyedropper tool to pick a color directly from the screen.",
BackgroundBrush = new SpriteBrush(Editor.Instance.Icons.Search32),
BackgroundColor = style.Foreground,
BackgroundColorHighlighted = style.Foreground.RGBMultiplied(0.9f),
@@ -223,9 +241,6 @@ namespace FlaxEditor.GUI.Dialogs
Parent = this,
};
_cEyedropper.Clicked += OnEyedropStart;
- _cEyedropper.Height = (_cValue.Bottom - _cEyedropper.Y) * 0.5f;
- _cEyedropper.Width = _cEyedropper.Height;
- _cEyedropper.X -= _cEyedropper.Width;
// Set initial color
SelectedColor = initialValue;
@@ -244,7 +259,7 @@ namespace FlaxEditor.GUI.Dialogs
}
}
- // Set color of button to current value;
+ // Set color of button to current value
button.BackgroundColor = _value;
button.BackgroundColorHighlighted = _value;
button.BackgroundColorSelected = _value.RGBMultiplied(0.8f);
@@ -256,10 +271,10 @@ namespace FlaxEditor.GUI.Dialogs
var savedColors = JsonSerializer.Serialize(_savedColors, typeof(List));
Editor.Instance.ProjectCache.SetCustomData("ColorPickerSavedColors", savedColors);
- // create new + button
- if (_savedColorButtons.Count < 8)
+ // Create new + button
+ if (_savedColorButtons.Count < SavedColorsAmount)
{
- var savedColorButton = new Button(PickerMargin * (_savedColorButtons.Count + 1) + SavedColorButtonWidth * _savedColorButtons.Count, Height - SavedColorButtonHeight - PickerMargin, SavedColorButtonWidth, SavedColorButtonHeight)
+ var savedColorButton = new Button(PickerMargin * (_savedColorButtons.Count + 1) + SavedColorButtonWidth * _savedColorButtons.Count, _cHex.Bottom + 40.0f + ColorPreviewHeight * 0.5f, SavedColorButtonWidth, SavedColorButtonHeight)
{
Text = "+",
Parent = this,
@@ -276,11 +291,32 @@ namespace FlaxEditor.GUI.Dialogs
}
}
+ private void SelectedTabChanged(Tabs.Tabs tabs)
+ {
+ if (_rgbPanel == null || _hsvPanel == null)
+ return;
+
+ switch (tabs.SelectedTabIndex)
+ {
+ // RGB
+ case 0:
+ _rgbPanel.Visible = true;
+ _hsvPanel.Visible = false;
+ break;
+ // HSV
+ case 1:
+ _rgbPanel.Visible = false;
+ _hsvPanel.Visible = true;
+ break;
+ }
+ }
+
private void OnColorPicked(Color32 colorPicked)
{
if (_activeEyedropper)
{
_activeEyedropper = false;
+ _cEyedropper.BackgroundColor = _cEyedropper.BackgroundColorHighlighted = Style.Current.Foreground;
SelectedColor = colorPicked;
ScreenUtilities.PickColorDone -= OnColorPicked;
}
@@ -289,6 +325,7 @@ namespace FlaxEditor.GUI.Dialogs
private void OnEyedropStart()
{
_activeEyedropper = true;
+ _cEyedropper.BackgroundColor = _cEyedropper.BackgroundColorHighlighted = Style.Current.BackgroundHighlighted;
ScreenUtilities.PickColor();
ScreenUtilities.PickColorDone += OnColorPicked;
}
@@ -340,64 +377,76 @@ namespace FlaxEditor.GUI.Dialogs
base.Draw();
- // RGBA
- var rgbaR = new Rectangle(_cRed.Left - ChannelTextWidth, _cRed.Y, 10000, _cRed.Height);
- Render2D.DrawText(style.FontMedium, "R", rgbaR, textColor, TextAlignment.Near, TextAlignment.Center);
- rgbaR.Location.Y = _cGreen.Y;
- Render2D.DrawText(style.FontMedium, "G", rgbaR, textColor, TextAlignment.Near, TextAlignment.Center);
- rgbaR.Location.Y = _cBlue.Y;
- Render2D.DrawText(style.FontMedium, "B", rgbaR, textColor, TextAlignment.Near, TextAlignment.Center);
- rgbaR.Location.Y = _cAlpha.Y;
- Render2D.DrawText(style.FontMedium, "A", rgbaR, textColor, TextAlignment.Near, TextAlignment.Center);
+ switch (_hsvRGBTabs.SelectedTabIndex)
+ {
+ // RGB
+ case 0:
+ var rgbRect = new Rectangle(_hsvRGBTabs.Left + PickerMargin, _hsvRGBTabs.Top + TabHeight + PickerMargin, 10000, _cRed.Height);
+ Render2D.DrawText(style.FontMedium, "R", rgbRect, textColor, TextAlignment.Near, TextAlignment.Center);
+ rgbRect.Location.Y += _cRed.Height + ChannelsMargin;
+ Render2D.DrawText(style.FontMedium, "G", rgbRect, textColor, TextAlignment.Near, TextAlignment.Center);
+ rgbRect.Location.Y += _cRed.Height + ChannelsMargin;
+ Render2D.DrawText(style.FontMedium, "B", rgbRect, textColor, TextAlignment.Near, TextAlignment.Center);
+ break;
+ // HSV
+ case 1:
+ // Left
+ var hsvLeftRect = new Rectangle(_hsvRGBTabs.Left + PickerMargin, _hsvRGBTabs.Top + TabHeight + PickerMargin, 10000, _cHue.Height);
+ Render2D.DrawText(style.FontMedium, "H", hsvLeftRect, textColor, TextAlignment.Near, TextAlignment.Center);
+ hsvLeftRect.Location.Y += _cHue.Height + ChannelsMargin;
+ Render2D.DrawText(style.FontMedium, "S", hsvLeftRect, textColor, TextAlignment.Near, TextAlignment.Center);
+ hsvLeftRect.Location.Y += _cHue.Height + ChannelsMargin;
+ Render2D.DrawText(style.FontMedium, "V", hsvLeftRect, textColor, TextAlignment.Near, TextAlignment.Center);
- // HSV left
- var hsvHl = new Rectangle(_cHue.Left - ChannelTextWidth, _cHue.Y, 10000, _cHue.Height);
- Render2D.DrawText(style.FontMedium, "H", hsvHl, textColor, TextAlignment.Near, TextAlignment.Center);
- hsvHl.Location.Y = _cSaturation.Y;
- Render2D.DrawText(style.FontMedium, "S", hsvHl, textColor, TextAlignment.Near, TextAlignment.Center);
- hsvHl.Location.Y = _cValue.Y;
- Render2D.DrawText(style.FontMedium, "V", hsvHl, textColor, TextAlignment.Near, TextAlignment.Center);
+ // Right
+ var hsvRightRect = new Rectangle(_hsvRGBTabs.Right - HSVRGBTextWidth, _hsvRGBTabs.Top + TabHeight + PickerMargin, ChannelTextWidth, _cHue.Height);
+ Render2D.DrawText(style.FontMedium, "°", hsvRightRect, textColor, TextAlignment.Near, TextAlignment.Center);
+ hsvRightRect.Location.Y += _cHue.Height + ChannelsMargin;
+ Render2D.DrawText(style.FontMedium, "%", hsvRightRect, textColor, TextAlignment.Near, TextAlignment.Center);
+ hsvRightRect.Location.Y += _cHue.Height + ChannelsMargin;
+ Render2D.DrawText(style.FontMedium, "%", hsvRightRect, textColor, TextAlignment.Near, TextAlignment.Center);
+ break;
+ }
- // HSV right
- var hsvHr = new Rectangle(_cHue.Right + 2, _cHue.Y, 10000, _cHue.Height);
- Render2D.DrawText(style.FontMedium, "°", hsvHr, textColor, TextAlignment.Near, TextAlignment.Center);
- hsvHr.Location.Y = _cSaturation.Y;
- Render2D.DrawText(style.FontMedium, "%", hsvHr, textColor, TextAlignment.Near, TextAlignment.Center);
- hsvHr.Location.Y = _cValue.Y;
- Render2D.DrawText(style.FontMedium, "%", hsvHr, textColor, TextAlignment.Near, TextAlignment.Center);
+ // A
+ var alphaHexRect = new Rectangle(_hsvRGBTabs.Left + PickerMargin, _cAlpha.Top, ChannelTextWidth, _cAlpha.Height);
+ Render2D.DrawText(style.FontMedium, "A", alphaHexRect, textColor, TextAlignment.Near, TextAlignment.Center);
// Hex
- var hex = new Rectangle(_cHex.Left - 26, _cHex.Y, 10000, _cHex.Height);
- Render2D.DrawText(style.FontMedium, "Hex", hex, textColor, TextAlignment.Near, TextAlignment.Center);
+ alphaHexRect.Y += _cAlpha.Height + ChannelsMargin * 2.0f;
+ alphaHexRect.X -= 5.0f; // "Hex" is two characters wider than the other labels so we need to adjust for that
+ Render2D.DrawText(style.FontMedium, "Hex", alphaHexRect, textColor, TextAlignment.Far, TextAlignment.Center);
// Color difference
- var newRect = new Rectangle(_cOK.X - 3, _cHex.Bottom + PickerMargin, 130, 0);
- newRect.Size.Y = 50;
- Render2D.FillRectangle(newRect, Color.White);
- var smallRectSize = 10;
- var numHor = Mathf.FloorToInt(newRect.Width / smallRectSize);
- var numVer = Mathf.FloorToInt(newRect.Height / smallRectSize);
+ var differenceRect = new Rectangle(_hsvRGBTabs.Left, _cHex.Bottom + 40.0f, _hsvRGBTabs.Width, ColorPreviewHeight);
+
// Draw checkerboard for background of color to help with transparency
+ Render2D.FillRectangle(differenceRect, Color.White);
+ var smallRectSize = 10;
+ var numHor = Mathf.CeilToInt(differenceRect.Width / smallRectSize);
+ var numVer = Mathf.CeilToInt(differenceRect.Height / smallRectSize);
+ Render2D.PushClip(differenceRect);
for (int i = 0; i < numHor; i++)
{
for (int j = 0; j < numVer; j++)
{
if ((i + j) % 2 == 0)
{
- var rect = new Rectangle(newRect.X + smallRectSize * i, newRect.Y + smallRectSize * j, new Float2(smallRectSize));
+ var rect = new Rectangle(differenceRect.X + smallRectSize * i, differenceRect.Y + smallRectSize * j, new Float2(smallRectSize));
Render2D.FillRectangle(rect, Color.Gray);
}
}
}
- Render2D.FillRectangle(newRect, _value);
+ Render2D.PopClip();
+ Render2D.FillRectangle(differenceRect, _value);
}
///
protected override void OnShow()
{
- // Auto cancel on lost focus
+ // Apply changes on lost focus
#if !PLATFORM_LINUX
- ((WindowRootControl)Root).Window.LostFocus += OnWindowLostFocus;
+ ((WindowRootControl)Root).Window.LostFocus += OnSubmit;
#endif
base.OnShow();
@@ -410,6 +459,7 @@ namespace FlaxEditor.GUI.Dialogs
{
// Cancel eye dropping
_activeEyedropper = false;
+ _cEyedropper.BackgroundColor = _cEyedropper.BackgroundColorHighlighted = Style.Current.Foreground;
ScreenUtilities.PickColorDone -= OnColorPicked;
return true;
}
@@ -483,20 +533,20 @@ namespace FlaxEditor.GUI.Dialogs
}
_savedColorButtons.Clear();
- CreateAllSaveButtons();
+ CreateAllSavedColorsButtons();
// Save new colors
var savedColors = JsonSerializer.Serialize(_savedColors, typeof(List));
Editor.Instance.ProjectCache.SetCustomData("ColorPickerSavedColors", savedColors);
}
- private void CreateAllSaveButtons()
+ private void CreateAllSavedColorsButtons()
{
// Create saved color buttons
for (int i = 0; i < _savedColors.Count; i++)
{
var savedColor = _savedColors[i];
- var savedColorButton = new Button(PickerMargin * (i + 1) + SavedColorButtonWidth * i, Height - SavedColorButtonHeight - PickerMargin, SavedColorButtonWidth, SavedColorButtonHeight)
+ var savedColorButton = new Button(PickerMargin * (i + 1) + SavedColorButtonWidth * i, _cHex.Bottom + 40.0f + ColorPreviewHeight * 0.5f, SavedColorButtonWidth, SavedColorButtonHeight)
{
Parent = this,
Tag = savedColor,
@@ -507,9 +557,9 @@ namespace FlaxEditor.GUI.Dialogs
savedColorButton.ButtonClicked += OnSavedColorButtonClicked;
_savedColorButtons.Add(savedColorButton);
}
- if (_savedColors.Count < 8)
+ if (_savedColors.Count < SavedColorsAmount)
{
- var savedColorButton = new Button(PickerMargin * (_savedColors.Count + 1) + SavedColorButtonWidth * _savedColors.Count, Height - SavedColorButtonHeight - PickerMargin, SavedColorButtonWidth, SavedColorButtonHeight)
+ var savedColorButton = new Button(PickerMargin * (_savedColors.Count + 1) + SavedColorButtonWidth * _savedColors.Count, _cHex.Bottom + 40.0f + ColorPreviewHeight * 0.5f, SavedColorButtonWidth, SavedColorButtonHeight)
{
Text = "+",
Parent = this,
@@ -521,19 +571,6 @@ namespace FlaxEditor.GUI.Dialogs
}
}
- private void OnWindowLostFocus()
- {
- // Auto apply color on defocus
- var autoAcceptColorPickerChange = Editor.Instance.Options.Options.Interface.AutoAcceptColorPickerChange;
- if (_useDynamicEditing && _initialValue != _value && _canPassLastChangeEvent && autoAcceptColorPickerChange)
- {
- _canPassLastChangeEvent = false;
- _onChanged?.Invoke(_value, false);
- }
-
- OnCancel();
- }
-
///
public override void OnSubmit()
{
@@ -541,6 +578,9 @@ namespace FlaxEditor.GUI.Dialogs
return;
_disableEvents = true;
+ // Ensure the cursor is restored
+ Cursor = CursorType.Default;
+
// Send color event if modified
if (_value != _initialValue)
{
@@ -557,6 +597,9 @@ namespace FlaxEditor.GUI.Dialogs
return;
_disableEvents = true;
+ // Ensure the cursor is restored
+ Cursor = CursorType.Default;
+
// Restore color if modified
if (_useDynamicEditing && _initialValue != _value && _canPassLastChangeEvent)
{
diff --git a/Source/Editor/Options/InterfaceOptions.cs b/Source/Editor/Options/InterfaceOptions.cs
index f26506c74..50f7c6f04 100644
--- a/Source/Editor/Options/InterfaceOptions.cs
+++ b/Source/Editor/Options/InterfaceOptions.cs
@@ -207,13 +207,6 @@ namespace FlaxEditor.Options
[EditorDisplay("Interface"), EditorOrder(280), Tooltip("Editor content window orientation.")]
public FlaxEngine.GUI.Orientation ContentWindowOrientation { get; set; } = FlaxEngine.GUI.Orientation.Horizontal;
- ///
- /// If checked, color pickers will always modify the color unless 'Cancel' if pressed, otherwise color won't change unless 'Ok' is pressed.
- ///
- [DefaultValue(true)]
- [EditorDisplay("Interface"), EditorOrder(290)]
- public bool AutoAcceptColorPickerChange { get; set; } = true;
-
///
/// Gets or sets the formatting option for numeric values in the editor.
///