Merge branch 'VISjectIsNowMoreVISuallyAppealingAndLegible' of https://github.com/xxSeys1/FlaxEngine into xxSeys1-VISjectIsNowMoreVISuallyAppealingAndLegible

This commit is contained in:
Wojtek Figat
2026-03-31 15:16:55 +02:00
27 changed files with 454 additions and 153 deletions

View File

@@ -102,8 +102,14 @@ namespace FlaxEditor.Surface.Archetypes
outline = style.BorderHighlighted;
else if (_editor._node.SelectedAnimationIndex == _index)
outline = style.BackgroundSelected;
var features = Render2D.Features;
Render2D.Features = features & ~Render2D.RenderingFeatures.VertexSnapping;
Render2D.DrawSprite(icon, rect.MakeExpanded(4.0f), outline);
Render2D.DrawSprite(icon, rect, style.Foreground);
Render2D.Features = features;
}
/// <inheritdoc />

View File

@@ -79,7 +79,7 @@ namespace FlaxEditor.Surface.Archetypes
: base(id, context, nodeArch, groupArch)
{
var marginX = FlaxEditor.Surface.Constants.NodeMarginX;
var uiStartPosY = FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize;
var uiStartPosY = FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight;
var editButton = new Button(marginX, uiStartPosY, 246, 20)
{

View File

@@ -70,6 +70,9 @@ namespace FlaxEditor.Surface.Archetypes
if (box.ID != _assetBox.ID)
return;
_assetSelect.Visible = !box.HasAnyConnection;
if (!Archetype.UseFixedSize)
ResizeAuto();
}
}
@@ -243,8 +246,8 @@ namespace FlaxEditor.Surface.Archetypes
{
Type = NodeElementType.Input,
Position = new Float2(
FlaxEditor.Surface.Constants.NodeMarginX - FlaxEditor.Surface.Constants.BoxOffsetX,
FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize + ylevel * FlaxEditor.Surface.Constants.LayoutOffsetY),
FlaxEditor.Surface.Constants.NodeMarginX,
FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight + ylevel * FlaxEditor.Surface.Constants.LayoutOffsetY),
Text = "Pose " + _blendPoses.Count,
Single = true,
ValueIndex = -1,
@@ -263,7 +266,7 @@ namespace FlaxEditor.Surface.Archetypes
private void UpdateHeight()
{
float nodeHeight = 10 + (Mathf.Max(_blendPoses.Count, 1) + 3) * FlaxEditor.Surface.Constants.LayoutOffsetY;
Height = nodeHeight + FlaxEditor.Surface.Constants.NodeMarginY * 2 + FlaxEditor.Surface.Constants.NodeHeaderSize + FlaxEditor.Surface.Constants.NodeFooterSize;
Height = nodeHeight + FlaxEditor.Surface.Constants.NodeMarginY * 2 + FlaxEditor.Surface.Constants.NodeHeaderHeight + FlaxEditor.Surface.Constants.NodeFooterSize;
}
/// <inheritdoc />
@@ -932,6 +935,7 @@ namespace FlaxEditor.Surface.Archetypes
Title = "Copy Node",
Description = "Copies the skeleton node transformation data (in local space)",
Flags = NodeFlags.AnimGraph,
UseFixedSize = true,
Size = new Float2(260, 140),
DefaultValues = new object[]
{

View File

@@ -189,13 +189,70 @@ namespace FlaxEditor.Surface.Archetypes
public override void Draw()
{
base.Draw();
var style = Style.Current;
var backgroundRect = new Rectangle(Float2.Zero, Size);
// Shadow
if (DrawBasicShadow)
{
var shadowRect = backgroundRect.MakeOffsetted(ShadowOffset);
Render2D.FillRectangle(shadowRect, Color.Black.AlphaMultiplied(0.125f));
}
// Background
Render2D.FillRectangle(backgroundRect, ArchetypeColor);
// Breakpoint hit
if (Breakpoint.Hit)
{
var colorTop = Color.OrangeRed;
var colorBottom = Color.Red;
var time = DateTime.Now - Engine.StartupTime;
Render2D.DrawRectangle(backgroundRect.MakeExpanded(Mathf.Lerp(3.0f, 12.0f, Mathf.Sin((float)time.TotalSeconds * 10.0f) * 0.5f + 0.5f)), colorTop, colorTop, colorBottom, colorBottom, 2.0f);
}
// Header
var headerColor = style.BackgroundHighlighted;
if (_headerRect.Contains(ref _mousePosition) && !Surface.IsConnecting && !Surface.IsSelecting)
headerColor *= 1.07f;
Render2D.FillRectangle(_headerRect, style.BackgroundHighlighted);
Render2D.DrawText(style.FontLarge, Title, _headerTextRect, style.Foreground, TextAlignment.Near, TextAlignment.Center, TextWrapping.NoWrap, 1f, FlaxEditor.Surface.Constants.NodeHeaderTextScale);
// Close button
if ((Archetype.Flags & NodeFlags.NoCloseButton) == 0 && Surface.CanEdit)
{
bool highlightClose = _closeButtonRect.Contains(_mousePosition) && !Surface.IsConnecting && !Surface.IsSelecting;
DrawCloseButton(_closeButtonRect, highlightClose ? style.Foreground : style.ForegroundGrey);
}
DrawChildren();
// Selection outline
if (_isSelected)
{
var colorTop = Color.Orange;
var colorBottom = Color.OrangeRed;
Render2D.DrawRectangle(backgroundRect, colorTop, colorTop, colorBottom, colorBottom, 2.5f);
}
// Breakpoint dot
if (Breakpoint.Set)
{
var icon = Breakpoint.Enabled ? Surface.Style.Icons.BoxClose : Surface.Style.Icons.BoxOpen;
Render2D.DrawSprite(icon, new Rectangle(-7, -7, 16, 16), new Color(0.9f, 0.9f, 0.9f));
Render2D.DrawSprite(icon, new Rectangle(-6, -6, 14, 14), new Color(0.894117647f, 0.0784313725f, 0.0f));
}
if (highlightBox != null)
Render2D.DrawRectangle(highlightBox.Bounds, style.BorderHighlighted, 2f);
// Debug Info
if (!string.IsNullOrEmpty(_debugInfo))
{
var style = Style.Current;
Render2D.DrawText(style.FontSmall, _debugInfo, new Rectangle(4, _headerRect.Bottom + 4, _debugInfoSize), style.Foreground);
// Draw an extra background to cover the archetype color colored node background and make text more legible
Render2D.FillRectangle(new Rectangle(0, _headerRect.Bottom + 4, Width, Height - _headerRect.Bottom - 4), style.BackgroundHighlighted);
Render2D.DrawText(style.FontSmall, _debugInfo, new Rectangle(4, _headerRect.Bottom + 7, _debugInfoSize), style.Foreground, scale: 0.8f);
}
// Debug relevancy outline
@@ -203,7 +260,7 @@ namespace FlaxEditor.Surface.Archetypes
{
var colorTop = Color.LightYellow;
var colorBottom = Color.Yellow;
var backgroundRect = new Rectangle(Float2.One, Size - new Float2(2.0f));
backgroundRect = new Rectangle(Float2.One, Size - new Float2(2.0f));
Render2D.DrawRectangle(backgroundRect, colorTop, colorTop, colorBottom, colorBottom);
}
}
@@ -415,8 +472,8 @@ namespace FlaxEditor.Surface.Archetypes
// Setup boxes
_input = (InputBox)GetBox(0);
_output = (OutputBox)GetBox(1);
_input.ConnectionOffset = new Float2(0, FlaxEditor.Surface.Constants.BoxSize * -0.5f);
_output.ConnectionOffset = new Float2(0, FlaxEditor.Surface.Constants.BoxSize * 0.5f);
_input.ConnectionOffset = new Float2(0, FlaxEditor.Surface.Constants.BoxRowHeight * -0.5f);
_output.ConnectionOffset = new Float2(0, FlaxEditor.Surface.Constants.BoxRowHeight * 0.5f);
// Setup node type and data
var flagsRoot = NodeFlags.NoRemove | NodeFlags.NoCloseButton | NodeFlags.NoSpawnViaPaste;
@@ -515,7 +572,7 @@ namespace FlaxEditor.Surface.Archetypes
height += decorator.Height + DecoratorsMarginY;
width = Mathf.Max(width, decorator.Width - FlaxEditor.Surface.Constants.NodeCloseButtonSize - 2 * DecoratorsMarginX);
}
Size = new Float2(width + FlaxEditor.Surface.Constants.NodeMarginX * 2 + FlaxEditor.Surface.Constants.NodeCloseButtonSize, height + FlaxEditor.Surface.Constants.NodeHeaderSize + FlaxEditor.Surface.Constants.NodeFooterSize);
Size = new Float2(width + FlaxEditor.Surface.Constants.NodeMarginX * 2 + FlaxEditor.Surface.Constants.NodeCloseButtonSize, height + FlaxEditor.Surface.Constants.NodeHeaderHeight);
UpdateRectangles();
}
@@ -536,13 +593,13 @@ namespace FlaxEditor.Surface.Archetypes
if (decorator.IndexInParent < indexInParent)
decorator.IndexInParent = indexInParent + 1; // Push elements above the node
}
const float footerSize = FlaxEditor.Surface.Constants.NodeFooterSize;
const float headerSize = FlaxEditor.Surface.Constants.NodeHeaderSize;
const float headerHeight = FlaxEditor.Surface.Constants.NodeHeaderHeight;
const float closeButtonMargin = FlaxEditor.Surface.Constants.NodeCloseButtonMargin;
const float closeButtonSize = FlaxEditor.Surface.Constants.NodeCloseButtonSize;
_headerRect = new Rectangle(0, bounds.Y - Y, bounds.Width, headerSize);
float closeButtonSize = FlaxEditor.Surface.Constants.NodeCloseButtonSize * 0.75f;
_headerRect = new Rectangle(0, bounds.Y - Y, bounds.Width, headerHeight);
_headerTextRect = _headerRect with { X = 5f, Width = Width - closeButtonSize - closeButtonMargin * 4f };
_closeButtonRect = new Rectangle(bounds.Width - closeButtonSize - closeButtonMargin, _headerRect.Y + closeButtonMargin, closeButtonSize, closeButtonSize);
_footerRect = new Rectangle(0, bounds.Height - footerSize, bounds.Width, footerSize);
if (_output != null && _output.Visible)
{
_footerRect.Y -= ConnectionAreaHeight;
@@ -648,6 +705,8 @@ namespace FlaxEditor.Surface.Archetypes
private DragDecorator _dragDecorator;
private float _dragLocation = -1;
internal override bool DrawBasicShadow => false;
internal Decorator(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch)
: base(id, context, nodeArch, groupArch)
{
@@ -667,7 +726,7 @@ namespace FlaxEditor.Surface.Archetypes
}
}
protected override Color FooterColor => Color.Transparent;
protected override Color ArchetypeColor => Color.Transparent;
protected override Float2 CalculateNodeSize(float width, float height)
{
@@ -676,7 +735,7 @@ namespace FlaxEditor.Surface.Archetypes
width = Mathf.Max(width, _debugInfoSize.X + 8.0f);
height += _debugInfoSize.Y + 8.0f;
}
return new Float2(width + FlaxEditor.Surface.Constants.NodeCloseButtonSize * 2 + DecoratorsMarginX * 2, height + FlaxEditor.Surface.Constants.NodeHeaderSize);
return new Float2(width + FlaxEditor.Surface.Constants.NodeCloseButtonSize * 2 + DecoratorsMarginX * 2, height + FlaxEditor.Surface.Constants.NodeHeaderHeight);
}
protected override void UpdateRectangles()
@@ -684,8 +743,14 @@ namespace FlaxEditor.Surface.Archetypes
base.UpdateRectangles();
_footerRect = Rectangle.Empty;
const float closeButtonMargin = FlaxEditor.Surface.Constants.NodeCloseButtonMargin;
float closeButtonSize = FlaxEditor.Surface.Constants.NodeCloseButtonSize * 0.75f;
_closeButtonRect = new Rectangle(Bounds.Width - closeButtonSize - closeButtonMargin, _headerRect.Y + closeButtonMargin, closeButtonSize, closeButtonSize);
if (_dragIcon != null)
_dragIcon.Bounds = new Rectangle(_closeButtonRect.X - _closeButtonRect.Width, _closeButtonRect.Y, _closeButtonRect.Size);
{
var dragIconRect = _closeButtonRect.MakeExpanded(5f);
_dragIcon.Bounds = new Rectangle(dragIconRect.X - dragIconRect.Width, dragIconRect.Y, dragIconRect.Size);
}
}
protected override void UpdateTitle()
@@ -764,6 +829,11 @@ namespace FlaxEditor.Surface.Archetypes
node.ResizeAuto();
}
}
else
{
// Correctly size decorators when surface is loaded
Node.ResizeAuto();
}
}
/// <inheritdoc />

View File

@@ -173,10 +173,10 @@ namespace FlaxEditor.Surface.Archetypes
{
Op(1, "==", "Determines whether two values are equal", new[] { "equals" }),
Op(2, "!=", "Determines whether two values are not equal", new[] { "not equals" }),
Op(3, ">", "Determines whether the first value is greater than the other", new[] { "greater than", "larger than", "bigger than" }),
Op(4, "<", "Determines whether the first value is less than the other", new[] { "less than", "smaller than" }),
Op(5, "<=", "Determines whether the first value is less or equal to the other", new[] { "less equals than", "smaller equals than" }),
Op(6, ">=", "Determines whether the first value is greater or equal to the other", new[] { "greater equals than", "larger equals than", "bigger equals than" }),
Op(3, ">", "Determines whether the first value is greater than the other", new[] { "greater than", "larger than", "bigger than", "more than" }),
Op(4, "<", "Determines whether the first value is less than the other", new[] { "less than", "smaller than", "tinier than" }),
Op(5, "<=", "Determines whether the first value is less or equal to the other", new[] { "less equals than", "smaller equals than", "tinier equals than" }),
Op(6, ">=", "Determines whether the first value is greater or equal to the other", new[] { "greater equals than", "larger equals than", "bigger equals than", "more equals than" }),
new NodeArchetype
{
TypeID = 7,

View File

@@ -166,7 +166,7 @@ namespace FlaxEditor.Surface.Archetypes
_picker = new EnumComboBox(type)
{
EnumTypeValue = Values[0],
Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize, 160, 16),
Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight, 160, 16),
Parent = this,
};
_picker.ValueChanged += () => SetValue(0, _picker.EnumTypeValue);
@@ -218,7 +218,7 @@ namespace FlaxEditor.Surface.Archetypes
_output = (OutputBox)Elements[0];
_typePicker = new TypePickerControl
{
Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize, 160, 16),
Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight, 160, 16),
Parent = this,
};
_typePicker.ValueChanged += () => Set(3);
@@ -362,7 +362,7 @@ namespace FlaxEditor.Surface.Archetypes
_output = (OutputBox)Elements[0];
_keyTypePicker = new TypePickerControl
{
Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize, 160, 16),
Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight, 160, 16),
Parent = this,
};
_keyTypePicker.ValueChanged += OnKeyTypeChanged;
@@ -482,7 +482,7 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(bool))),
Description = "Constant boolean value",
Flags = NodeFlags.AllGraphs,
Size = new Float2(110, 20),
Size = new Float2(90, 20),
DefaultValues = new object[]
{
false
@@ -515,7 +515,7 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(int))),
Description = "Constant integer value",
Flags = NodeFlags.AllGraphs,
Size = new Float2(110, 20),
Size = new Float2(120, 20),
DefaultValues = new object[]
{
0
@@ -543,7 +543,7 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(float))),
Description = "Constant floating point",
Flags = NodeFlags.AllGraphs,
Size = new Float2(110, 20),
Size = new Float2(120, 20),
DefaultValues = new object[]
{
0.0f
@@ -750,7 +750,7 @@ namespace FlaxEditor.Surface.Archetypes
Title = "PI",
Description = "A value specifying the approximation of π which is 180 degrees",
Flags = NodeFlags.AllGraphs,
Size = new Float2(50, 20),
Size = new Float2(45, 20),
Elements = new[]
{
NodeElementArchetype.Factory.Output(0, "π", typeof(float), 0),
@@ -782,7 +782,7 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(uint))),
Description = "Constant unsigned integer value",
Flags = NodeFlags.AllGraphs,
Size = new Float2(170, 20),
Size = new Float2(130, 20),
DefaultValues = new object[]
{
0u
@@ -824,7 +824,7 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(double))),
Description = "Constant floating point",
Flags = NodeFlags.AllGraphs,
Size = new Float2(110, 20),
Size = new Float2(120, 20),
DefaultValues = new object[]
{
0.0d

View File

@@ -631,7 +631,7 @@ namespace FlaxEditor.Surface.Archetypes
}
/// <inheritdoc />
protected override Color FooterColor => new Color(200, 11, 112);
protected override Color ArchetypeColor => new Color(200, 11, 112);
/// <inheritdoc />
public override void OnLoaded(SurfaceNodeActions action)

View File

@@ -312,16 +312,17 @@ namespace FlaxEditor.Surface.Archetypes
: base(id, context, nodeArch, groupArch)
{
_sizeValueIndex = Archetype.TypeID == 8 ? 1 : 3; // Index of the Size stored in Values array
Float2 pos = new Float2(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize), size;
Float2 pos = new Float2(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight), size;
if (nodeArch.TypeID == 8)
{
pos += new Float2(60, 0);
size = new Float2(172, 200);
pos += new Float2(65, 0);
size = new Float2(160, 185);
_sizeMin = new Float2(240, 185);
}
else
{
pos += new Float2(0, 40);
size = new Float2(300, 200);
pos += new Float2(0, 40 + FlaxEditor.Utilities.Constants.UIMargin * 2f);
size = new Float2(300, 180);
}
_textBox = new CustomCodeTextBox
{
@@ -506,8 +507,8 @@ namespace FlaxEditor.Surface.Archetypes
Size = new Float2(300, 200),
DefaultValues = new object[]
{
"// Here you can add HLSL code\nOutput0 = Input0;",
new Float2(300, 200),
"// You can add HLSL code here\nOutput0 = Input0;",
new Float2(350, 200),
},
Elements = new[]
{
@@ -972,7 +973,7 @@ namespace FlaxEditor.Surface.Archetypes
Size = new Float2(300, 240),
DefaultValues = new object[]
{
"// Here you can add HLSL code\nfloat4 GetCustomColor()\n{\n\treturn float4(1, 0, 0, 1);\n}",
"// You can add HLSL code here\nfloat4 GetCustomColor()\n{\n\treturn float4(1, 0, 0, 1);\n}",
true,
(int)MaterialTemplateInputsMapping.Utilities,
new Float2(300, 240),

View File

@@ -121,7 +121,7 @@ namespace FlaxEditor.Surface.Archetypes
Render2D.DrawRectangle(new Rectangle(1, 0, Width - 2, Height - 1), Colors[idx]);
// Close button
Render2D.DrawSprite(style.Cross, _closeButtonRect, _closeButtonRect.Contains(_mousePosition) ? style.Foreground : style.ForegroundGrey);
DrawCloseButton(_closeButtonRect, _closeButtonRect.Contains(_mousePosition) ? style.Foreground : style.ForegroundGrey);
// Arrange button
var dragBarColor = _arrangeButtonRect.Contains(_mousePosition) ? style.Foreground : style.ForegroundGrey;
@@ -138,6 +138,12 @@ namespace FlaxEditor.Surface.Archetypes
}
}
/// <inheritdoc />
public override void Resize(float width, float height)
{
// Do nothing so module does not change size
}
private bool ArrangeAreaCheck(out int index, out Rectangle rect)
{
var barSidesExtend = 20.0f;
@@ -261,9 +267,9 @@ namespace FlaxEditor.Surface.Archetypes
const float closeButtonMargin = FlaxEditor.Surface.Constants.NodeCloseButtonMargin;
const float closeButtonSize = FlaxEditor.Surface.Constants.NodeCloseButtonSize;
_headerRect = new Rectangle(0, 0, Width, headerSize);
_closeButtonRect = new Rectangle(Width - closeButtonSize - closeButtonMargin, closeButtonMargin, closeButtonSize, closeButtonSize);
_closeButtonRect = new Rectangle(Width - closeButtonSize * 0.75f - closeButtonMargin, closeButtonMargin + 0.25f, closeButtonSize * 0.75f, closeButtonSize * 0.75f);
_footerRect = Rectangle.Empty;
_enabled.Location = new Float2(_closeButtonRect.X - _enabled.Width - 2, _closeButtonRect.Y);
_enabled.Location = new Float2(_closeButtonRect.X - _enabled.Width - 2, _closeButtonRect.Y - 0.25f);
_arrangeButtonRect = new Rectangle(_enabled.X - closeButtonSize - closeButtonMargin, closeButtonMargin, closeButtonSize, closeButtonSize);
}
@@ -461,7 +467,7 @@ namespace FlaxEditor.Surface.Archetypes
/// <summary>
/// The particle module node elements offset applied to controls to reduce default surface node header thickness.
/// </summary>
private const float NodeElementsOffset = 16.0f - Surface.Constants.NodeHeaderSize;
private const float NodeElementsOffset = 16.0f - Surface.Constants.NodeHeaderHeight;
private const NodeFlags DefaultModuleFlags = NodeFlags.ParticleEmitterGraph | NodeFlags.NoSpawnViaGUI | NodeFlags.NoMove;

View File

@@ -74,7 +74,7 @@ namespace FlaxEditor.Surface.Archetypes
/// <summary>
/// The header height.
/// </summary>
public const float HeaderHeight = FlaxEditor.Surface.Constants.NodeHeaderSize;
public const float HeaderHeight = FlaxEditor.Surface.Constants.NodeHeaderHeight;
/// <summary>
/// Gets the type of the module.
@@ -199,7 +199,7 @@ namespace FlaxEditor.Surface.Archetypes
DrawChildren();
// Options border
var optionsAreaStart = FlaxEditor.Surface.Constants.NodeHeaderSize + 3.0f;
var optionsAreaStart = FlaxEditor.Surface.Constants.NodeHeaderHeight + 3.0f;
var optionsAreaHeight = 7 * FlaxEditor.Surface.Constants.LayoutOffsetY + 6.0f;
Render2D.DrawRectangle(new Rectangle(1, optionsAreaStart, Width - 2, optionsAreaHeight), style.BackgroundSelected);
@@ -341,6 +341,7 @@ namespace FlaxEditor.Surface.Archetypes
Title = "Particle Emitter",
Description = "Main particle emitter node. Contains a set of modules per emitter context. Modules are executed in order from top to bottom of the stack.",
Flags = NodeFlags.ParticleEmitterGraph | NodeFlags.NoRemove | NodeFlags.NoSpawnViaGUI | NodeFlags.NoSpawnViaPaste | NodeFlags.NoCloseButton,
UseFixedSize = true,
Size = new Float2(300, 600),
DefaultValues = new object[]
{

View File

@@ -57,7 +57,7 @@ namespace FlaxEditor.Surface.Archetypes
{
_textureGroupPicker = new ComboBox
{
Location = new Float2(FlaxEditor.Surface.Constants.NodeMarginX + 50, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize + FlaxEditor.Surface.Constants.LayoutOffsetY * _level),
Location = new Float2(FlaxEditor.Surface.Constants.NodeMarginX + 50, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight + FlaxEditor.Surface.Constants.LayoutOffsetY * _level),
Width = 100,
Parent = this,
};
@@ -134,7 +134,7 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new Constants.ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Texture))),
Description = "Two dimensional texture object",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(140, 120),
Size = new Float2(140, 140),
DefaultValues = new object[]
{
Guid.Empty
@@ -158,7 +158,7 @@ namespace FlaxEditor.Surface.Archetypes
AlternativeTitles = new string[] { "UV", "UVs" },
Description = "Texture coordinates",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(150, 30),
Size = new Float2(160, 20),
DefaultValues = new object[]
{
0u
@@ -239,7 +239,7 @@ namespace FlaxEditor.Surface.Archetypes
NodeElementArchetype.Factory.Input(3, "Max Steps", true, typeof(float), 3, 2),
NodeElementArchetype.Factory.Input(4, "Heightmap Texture", true, typeof(FlaxEngine.Object), 4),
NodeElementArchetype.Factory.Output(0, "Parallax UVs", typeof(Float2), 5),
NodeElementArchetype.Factory.Text(Surface.Constants.BoxSize + 4, 5 * Surface.Constants.LayoutOffsetY, "Channel"),
NodeElementArchetype.Factory.Text(Surface.Constants.BoxRowHeight + 4, 5 * Surface.Constants.LayoutOffsetY, "Channel"),
NodeElementArchetype.Factory.ComboBox(70, 5 * Surface.Constants.LayoutOffsetY, 50, 3, new[]
{
"R",
@@ -493,7 +493,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 18,
Title = "Lightmap UV",
AlternativeTitles = new string[] { "Lightmap TexCoord" },
AlternativeTitles = new string[] { "Lightmap TexCoord" },
Description = "Lightmap UVs",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(110, 20),

View File

@@ -467,7 +467,7 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new CurveNode<T>(id, context, arch, groupArch),
Description = "An animation spline represented by a set of keyframes, each representing an endpoint of a Bezier curve.",
Flags = NodeFlags.AllGraphs,
Size = new Float2(400, 180),
Size = new Float2(400, 180.0f),
DefaultValues = new object[]
{
// Keyframes count
@@ -485,7 +485,7 @@ namespace FlaxEditor.Surface.Archetypes
zero, // Tangent In
zero, // Tangent Out
// Empty keys zero-6
// Empty keys 0-6
0.0f, zero, zero, zero,
0.0f, zero, zero, zero,
0.0f, zero, zero, zero,
@@ -515,13 +515,12 @@ namespace FlaxEditor.Surface.Archetypes
base.OnLoaded(action);
// Create curve editor
var upperLeft = GetBox(0).BottomLeft;
var upperRight = GetBox(1).BottomRight;
float curveMargin = 20.0f;
var upperLeft = GetBox(0).BottomRight;
var upperRight = GetBox(1).BottomLeft;
_curve = new BezierCurveEditor<T>
{
MaxKeyframes = 7,
Bounds = new Rectangle(upperLeft + new Float2(curveMargin, 10.0f), upperRight.X - upperLeft.X - curveMargin * 2.0f, 140.0f),
Bounds = new Rectangle(upperLeft + new Float2(0f, 10.0f), upperRight.X - upperLeft.X - 8.0f, 135.0f),
Parent = this,
AnchorMax = Float2.One,
};
@@ -841,7 +840,7 @@ namespace FlaxEditor.Surface.Archetypes
_picker = new TypePickerControl
{
Type = ScriptType.FlaxObject,
Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX + 20, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize, 160, 16),
Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX + 20, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight, 160, 16),
Parent = this,
};
_picker.ValueChanged += () => SetValue(0, _picker.ValueTypeName);
@@ -910,7 +909,7 @@ namespace FlaxEditor.Surface.Archetypes
_picker = new TypePickerControl
{
Type = ScriptType.Object,
Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize, 140, 16),
Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight, 140, 16),
Parent = this,
};
_picker.ValueChanged += () => SetValue(0, _picker.ValueTypeName);
@@ -961,7 +960,7 @@ namespace FlaxEditor.Surface.Archetypes
_picker = new TypePickerControl
{
Type = ScriptType.FlaxObject,
Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX + 20, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize, 160, 16),
Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX + 20, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight, 160, 16),
Parent = this,
};
_picker.ValueChanged += () => SetValue(0, _picker.ValueTypeName);
@@ -1012,7 +1011,7 @@ namespace FlaxEditor.Surface.Archetypes
_picker = new TypePickerControl
{
Type = type,
Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX + 20, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize, 160, 16),
Bounds = new Rectangle(FlaxEditor.Surface.Constants.NodeMarginX + 20, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderHeight, 160, 16),
Parent = this,
};
_picker.ValueChanged += () => SetValue(0, _picker.ValueTypeName);
@@ -1071,7 +1070,11 @@ namespace FlaxEditor.Surface.Archetypes
internal class RerouteNode : SurfaceNode, IConnectionInstigator
{
internal static readonly Float2 DefaultSize = new Float2(FlaxEditor.Surface.Constants.BoxSize);
internal static readonly Float2 DefaultSize = new Float2(FlaxEditor.Surface.Constants.BoxRowHeight);
internal bool DrawDisabled => _input.AllConnectionsDisabled || _output.AllConnectionsDisabled;
internal override bool DrawBasicShadow => false;
private Rectangle _localBounds;
private InputBox _input;
private OutputBox _output;
@@ -1174,9 +1177,18 @@ namespace FlaxEditor.Surface.Archetypes
_footerRect = Rectangle.Empty;
}
/// <inheritdoc />
public override void Resize(float width, float height)
{
// Do nothing so the input and output boxes do not change position
}
/// <inheritdoc />
public override void Draw()
{
// Update active state of input
_input.IsActive = !_output.AllConnectionsDisabled;
var style = Surface.Style;
var connectionColor = style.Colors.Default;
var type = ScriptType.Null;
@@ -1190,6 +1202,10 @@ namespace FlaxEditor.Surface.Archetypes
Surface.Style.GetConnectionColor(type, hints, out connectionColor);
}
// Draw the box as disabled if needed
if (DrawDisabled)
connectionColor = connectionColor * 0.6f;
if (!_input.HasAnyConnection)
Render2D.FillRectangle(new Rectangle(-barHorizontalOffset - barHeight * 2, (DefaultSize.Y - barHeight) / 2, barHeight * 2, barHeight), connectionColor);
if (!_output.HasAnyConnection)
@@ -1200,6 +1216,11 @@ namespace FlaxEditor.Surface.Archetypes
icon = type.IsVoid ? style.Icons.ArrowClose : style.Icons.BoxClose;
else
icon = type.IsVoid ? style.Icons.ArrowOpen : style.Icons.BoxOpen;
// Shadow
var shadowRect = _localBounds.MakeOffsetted(ShadowOffset);
Render2D.DrawSprite(icon, shadowRect, Color.Black.AlphaMultiplied(0.125f));
Render2D.DrawSprite(icon, _localBounds, connectionColor);
base.Draw();
@@ -1507,6 +1528,7 @@ namespace FlaxEditor.Surface.Archetypes
Description = "Linear color gradient sampler",
Flags = NodeFlags.AllGraphs,
Size = new Float2(400, 150.0f),
UseFixedSize = true,
DefaultValues = new object[]
{
// Stops count
@@ -1826,6 +1848,7 @@ namespace FlaxEditor.Surface.Archetypes
Description = "Reroute a connection.",
Flags = NodeFlags.NoCloseButton | NodeFlags.NoSpawnViaGUI | NodeFlags.AllGraphs,
Size = RerouteNode.DefaultSize,
UseFixedSize = true,
ConnectionsHints = ConnectionsHint.All,
IndependentBoxes = new int[] { 0 },
DependentBoxes = new int[] { 1 },

View File

@@ -13,46 +13,61 @@ namespace FlaxEditor.Surface
/// <summary>
/// The node close button size.
/// </summary>
public const float NodeCloseButtonSize = 12.0f;
public const float NodeCloseButtonSize = 10.0f;
/// <summary>
/// The node close button margin from the edges.
/// </summary>
public const float NodeCloseButtonMargin = 2.0f;
public const float NodeCloseButtonMargin = 5.0f;
/// <summary>
/// The node header height.
/// </summary>
public const float NodeHeaderSize = 28.0f;
public const float NodeHeaderHeight = 25.0f;
/// <summary>
/// The scale of the header text.
/// </summary>
public const float NodeHeaderTextScale = 0.8f;
/// <summary>
/// The node footer height.
/// </summary>
public const float NodeFooterSize = 4.0f;
public const float NodeFooterSize = 2.0f;
/// <summary>
/// The node left margin.
/// The horizontal node margin.
/// </summary>
public const float NodeMarginX = 5.0f;
public const float NodeMarginX = 6.0f;
/// <summary>
/// The node right margin.
/// The vertical node right margin.
/// </summary>
public const float NodeMarginY = 5.0f;
public const float NodeMarginY = 8.0f;
/// <summary>
/// The box position offset on the x axis.
/// The width of the row that is started by a box.
/// </summary>
public const float BoxOffsetX = 2.0f;
public const float BoxRowHeight = 19.0f;
/// <summary>
/// The box size (with and height).
/// </summary>
public const float BoxSize = 20.0f;
public const float BoxSize = 15.0f;
/// <summary>
/// The node layout offset on the y axis (height of the boxes rows, etc.). It's used to make the design more consistent.
/// </summary>
public const float LayoutOffsetY = 20.0f;
public const float LayoutOffsetY = 24.0f;
/// <summary>
/// The offset between the box text and the box
/// </summary>
public const float BoxTextOffset = 1.65f;
/// <summary>
/// The width of the rectangle used to draw the box text.
/// </summary>
public const float BoxTextRectWidth = 500.0f;
}
}

View File

@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FlaxEditor.Scripting;
using FlaxEditor.Surface.Undo;
using FlaxEngine;
@@ -194,9 +195,19 @@ namespace FlaxEditor.Surface.Elements
set => _isActive = value;
}
/// <summary>
/// Gets if the box is disabled (user can still connect, but connections will be ignored).
/// </summary>
public bool IsDisabled => !(Enabled && IsActive);
/// <summary>
/// Gets a value indicating whether all connections are disabled.
/// </summary>
public bool AllConnectionsDisabled => Connections.All(c => c.IsDisabled);
/// <inheritdoc />
protected Box(SurfaceNode parentNode, NodeElementArchetype archetype, Float2 location)
: base(parentNode, archetype, location, new Float2(Constants.BoxSize), false)
: base(parentNode, archetype, location, new Float2(Constants.BoxRowHeight), false)
{
_currentType = DefaultType;
_isSingle = Archetype.Single;

View File

@@ -1442,8 +1442,8 @@ namespace FlaxEditor.Surface.Elements
// Draw text
var style = Style.Current;
var rect = new Rectangle(Width + 4, 0, 1410, Height);
Render2D.DrawText(style.FontSmall, Text, rect, Enabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Near, TextAlignment.Center);
var rect = new Rectangle(Width + Constants.BoxTextOffset, 0, Constants.BoxTextRectWidth, Height);
Render2D.DrawText(style.FontMedium, Text, rect, Enabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Near, TextAlignment.Center);
}
/// <inheritdoc />

View File

@@ -186,7 +186,7 @@ namespace FlaxEditor.Surface.Elements
Box targetBox = Connections[i];
var endPos = targetBox.ConnectionOrigin;
var highlight = DefaultConnectionThickness + Mathf.Max(startHighlight, targetBox.ConnectionsHighlightIntensity);
var alpha = targetBox.Enabled && targetBox.IsActive ? 1.0f : 0.6f;
var alpha = targetBox.IsDisabled ? 0.6f : 1.0f;
// We have to calculate an offset here to preserve the original color for when the default connection thickness is larger than 1
var highlightOffset = (highlight - (DefaultConnectionThickness - 1));
@@ -212,7 +212,7 @@ namespace FlaxEditor.Surface.Elements
// Draw all the connections
var startPos = ConnectionOrigin;
var endPos = targetBox.ConnectionOrigin;
var alpha = targetBox.Enabled && targetBox.IsActive ? 1.0f : 0.6f;
var alpha = targetBox.IsDisabled ? 0.6f : 1.0f;
var color = _currentTypeColor * alpha;
DrawConnection(Surface.Style, ref startPos, ref endPos, ref color, SelectedConnectionThickness);
}
@@ -230,8 +230,8 @@ namespace FlaxEditor.Surface.Elements
// Draw text
var style = Style.Current;
var rect = new Rectangle(-100, 0, 100 - 2, Height);
Render2D.DrawText(style.FontSmall, Text, rect, Enabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Far, TextAlignment.Center);
var rect = new Rectangle(-Constants.BoxTextRectWidth - Constants.BoxTextOffset * 2f, 0f, Constants.BoxTextRectWidth, Height);
Render2D.DrawText(style.FontMedium, Text, rect, Enabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Far, TextAlignment.Center);
}
}
}

View File

@@ -129,6 +129,11 @@ namespace FlaxEditor.Surface
/// </summary>
public NodeFlags Flags;
/// <summary>
/// If the node should use the <see cref="Size"/> as node size. If false, the node will auto resize based on its elements.
/// </summary>
public bool UseFixedSize = false;
/// <summary>
/// Title text.
/// </summary>

View File

@@ -3,8 +3,9 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using FlaxEditor.CustomEditors;
using FlaxEditor.GUI.Input;
using FlaxEditor.Scripting;
using FlaxEditor.Surface.Elements;
using FlaxEngine;
namespace FlaxEditor.Surface
@@ -78,12 +79,12 @@ namespace FlaxEditor.Surface
/// <summary>
/// Gets the actual element position on the y axis.
/// </summary>
public float ActualPositionY => Position.Y + Constants.NodeMarginY + Constants.NodeHeaderSize;
public float ActualPositionY => Position.Y + Constants.NodeMarginY + Constants.NodeHeaderHeight;
/// <summary>
/// Gets the actual element position.
/// </summary>
public Float2 ActualPosition => new Float2(Position.X + Constants.NodeMarginX, Position.Y + Constants.NodeMarginY + Constants.NodeHeaderSize);
public Float2 ActualPosition => new Float2(Position.X + Constants.NodeMarginX, Position.Y + Constants.NodeMarginY + Constants.NodeHeaderHeight);
/// <summary>
/// Node element archetypes factory object. Helps to build surface nodes archetypes.
@@ -106,8 +107,8 @@ namespace FlaxEditor.Surface
{
Type = NodeElementType.Input,
Position = new Float2(
Constants.NodeMarginX - Constants.BoxOffsetX,
Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY),
Constants.NodeMarginX,
Constants.NodeMarginY + Constants.NodeHeaderHeight + yLevel * Constants.LayoutOffsetY),
Text = text,
Single = single,
ValueIndex = valueIndex,
@@ -132,8 +133,8 @@ namespace FlaxEditor.Surface
{
Type = NodeElementType.Input,
Position = new Float2(
Constants.NodeMarginX - Constants.BoxOffsetX,
Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY),
Constants.NodeMarginX,
Constants.NodeMarginY + Constants.NodeHeaderHeight + yLevel * Constants.LayoutOffsetY),
Text = text,
Single = single,
ValueIndex = valueIndex,
@@ -157,8 +158,8 @@ namespace FlaxEditor.Surface
{
Type = NodeElementType.Output,
Position = new Float2(
Constants.NodeMarginX - Constants.BoxSize + Constants.BoxOffsetX,
Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY),
-Constants.NodeMarginX,
Constants.NodeMarginY + Constants.NodeHeaderHeight + yLevel * Constants.LayoutOffsetY),
Text = text,
Single = single,
ValueIndex = -1,
@@ -182,8 +183,8 @@ namespace FlaxEditor.Surface
{
Type = NodeElementType.Output,
Position = new Float2(
Constants.NodeMarginX - Constants.BoxSize + Constants.BoxOffsetX,
Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY),
-Constants.NodeMarginX,
Constants.NodeMarginY + Constants.NodeHeaderHeight + yLevel * Constants.LayoutOffsetY),
Text = text,
Single = single,
ValueIndex = -1,
@@ -205,6 +206,7 @@ namespace FlaxEditor.Surface
{
Type = NodeElementType.BoolValue,
Position = new Float2(x, y),
Size = new Float2(16f),
Text = null,
Single = false,
ValueIndex = valueIndex,
@@ -228,7 +230,8 @@ namespace FlaxEditor.Surface
return new NodeElementArchetype
{
Type = NodeElementType.IntegerValue,
Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderSize + y),
Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderHeight + y),
Size = new Float2(50f, IntegerValue.DefaultHeight),
Text = null,
Single = false,
ValueIndex = valueIndex,
@@ -254,7 +257,8 @@ namespace FlaxEditor.Surface
return new NodeElementArchetype
{
Type = NodeElementType.UnsignedIntegerValue,
Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderSize + y),
Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderHeight + y),
Size = new Float2(50f, UnsignedIntegerValue.DefaultHeight),
Text = null,
Single = false,
ValueIndex = valueIndex,
@@ -280,7 +284,8 @@ namespace FlaxEditor.Surface
return new NodeElementArchetype
{
Type = NodeElementType.FloatValue,
Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderSize + y),
Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderHeight + y),
Size = new Float2(50f, FloatValueBox.DefaultHeight),
Text = null,
Single = false,
ValueIndex = valueIndex,
@@ -359,7 +364,8 @@ namespace FlaxEditor.Surface
return new NodeElementArchetype
{
Type = NodeElementType.ColorValue,
Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderSize + y),
Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderHeight + y),
Size = new Float2(32, 18),
Text = null,
Single = false,
ValueIndex = valueIndex,
@@ -382,6 +388,7 @@ namespace FlaxEditor.Surface
{
Type = NodeElementType.Asset,
Position = new Float2(x, y),
Size = new Float2(78f, 90f),
Text = type.FullName,
Single = false,
ValueIndex = valueIndex,
@@ -530,7 +537,7 @@ namespace FlaxEditor.Surface
return new NodeElementArchetype
{
Type = NodeElementType.TextBox,
Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderSize + y),
Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderHeight + y),
Size = new Float2(width, height),
Single = false,
ValueIndex = valueIndex,
@@ -595,7 +602,7 @@ namespace FlaxEditor.Surface
return new NodeElementArchetype
{
Type = NodeElementType.BoxValue,
Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderSize + y),
Position = new Float2(Constants.NodeMarginX + x, Constants.NodeMarginY + Constants.NodeHeaderHeight + y),
Text = null,
Single = false,
ValueIndex = valueIndex,

View File

@@ -60,84 +60,84 @@ namespace FlaxEditor.Surface
{
GroupID = 1,
Name = "Material",
Color = new Color(231, 76, 60),
Color = new Color(181, 89, 49),
Archetypes = Archetypes.Material.Nodes
},
new GroupArchetype
{
GroupID = 2,
Name = "Constants",
Color = new Color(243, 156, 18),
Color = new Color(163, 106, 21),
Archetypes = Archetypes.Constants.Nodes
},
new GroupArchetype
{
GroupID = 3,
Name = "Math",
Color = new Color(52, 152, 219),
Color = new Color(45, 126, 181),
Archetypes = Archetypes.Math.Nodes
},
new GroupArchetype
{
GroupID = 4,
Name = "Packing",
Color = new Color(155, 89, 182),
Color = new Color(124, 66, 143),
Archetypes = Archetypes.Packing.Nodes
},
new GroupArchetype
{
GroupID = 5,
Name = "Textures",
Color = new Color(46, 204, 113),
Color = new Color(43, 130, 83),
Archetypes = Archetypes.Textures.Nodes
},
new GroupArchetype
{
GroupID = 6,
Name = "Parameters",
Color = new Color(52, 73, 94),
Color = new Color(55, 78, 99),
Archetypes = Archetypes.Parameters.Nodes
},
new GroupArchetype
{
GroupID = 7,
Name = "Tools",
Color = new Color(149, 165, 166),
Color = new Color(88, 96, 97),
Archetypes = Archetypes.Tools.Nodes
},
new GroupArchetype
{
GroupID = 8,
Name = "Layers",
Color = new Color(249, 105, 116),
Color = new Color(189, 75, 81),
Archetypes = Archetypes.Layers.Nodes
},
new GroupArchetype
{
GroupID = 9,
Name = "Animations",
Color = new Color(105, 179, 160),
Color = new Color(72, 125, 107),
Archetypes = Archetypes.Animation.Nodes
},
new GroupArchetype
{
GroupID = 10,
Name = "Boolean",
Color = new Color(237, 28, 36),
Color = new Color(166, 27, 32),
Archetypes = Archetypes.Boolean.Nodes
},
new GroupArchetype
{
GroupID = 11,
Name = "Bitwise",
Color = new Color(181, 230, 29),
Color = new Color(96, 125, 34),
Archetypes = Archetypes.Bitwise.Nodes
},
new GroupArchetype
{
GroupID = 12,
Name = "Comparisons",
Color = new Color(148, 30, 34),
Color = new Color(166, 33, 57),
Archetypes = Archetypes.Comparisons.Nodes
},
// GroupID = 13 -> Custom Nodes provided externally
@@ -145,7 +145,7 @@ namespace FlaxEditor.Surface
{
GroupID = 14,
Name = "Particles",
Color = new Color(121, 210, 176),
Color = new Color(72, 125, 107),
Archetypes = Archetypes.Particles.Nodes
},
new GroupArchetype
@@ -166,7 +166,7 @@ namespace FlaxEditor.Surface
{
GroupID = 17,
Name = "Flow",
Color = new Color(237, 136, 64),
Color = new Color(181, 91, 33),
Archetypes = Archetypes.Flow.Nodes
},
new GroupArchetype

View File

@@ -59,7 +59,7 @@ namespace FlaxEditor.Surface
var width = _rootNode.Width;
var rootPos = _rootNode.Location;
var pos = rootPos;
pos.Y += Constants.NodeHeaderSize + 1.0f + 7 * Constants.LayoutOffsetY + 6.0f + 4.0f;
pos.Y += Constants.NodeHeaderHeight + 1.0f + 7 * Constants.LayoutOffsetY + 6.0f + 4.0f;
for (int i = 0; i < _rootNode.Headers.Length; i++)
{
@@ -67,7 +67,7 @@ namespace FlaxEditor.Surface
var modulesStart = pos - rootPos;
var modules = modulesGroups.FirstOrDefault(x => x.Key == header.ModuleType);
pos.Y += Constants.NodeHeaderSize + 2.0f;
pos.Y += Constants.NodeHeaderHeight + 2.0f;
if (modules != null)
{
foreach (var module in modules)

View File

@@ -74,6 +74,12 @@ namespace FlaxEditor.Surface
Resize(size.X, size.Y);
}
/// <inheritdoc />
public override void ResizeAuto()
{
// Do nothing, we want to put full control of node size into the users hands
}
/// <inheritdoc />
public override void Draw()
{

View File

@@ -56,10 +56,10 @@ namespace FlaxEditor.Surface
: base(id, context, nodeArch, groupArch)
{
_sizeValueIndex = 2; // Index of the Size stored in Values array
_sizeMin = new Float2(140.0f, Constants.NodeHeaderSize);
_sizeMin = new Float2(140.0f, Constants.NodeHeaderHeight);
_renameTextBox = new TextBox(false, 0, 0, Width)
{
Height = Constants.NodeHeaderSize,
Height = Constants.NodeHeaderHeight,
Visible = false,
Parent = this,
EndEditOnClick = false, // We have to handle this ourselves, otherwise the textbox instantly loses focus when double-clicking the header
@@ -124,11 +124,11 @@ namespace FlaxEditor.Surface
{
base.UpdateRectangles();
const float headerSize = Constants.NodeHeaderSize;
const float headerSize = Constants.NodeHeaderHeight;
const float buttonMargin = Constants.NodeCloseButtonMargin;
const float buttonSize = Constants.NodeCloseButtonSize;
_headerRect = new Rectangle(0, 0, Width, headerSize);
_closeButtonRect = new Rectangle(Width - buttonSize - buttonMargin, buttonMargin, buttonSize, buttonSize);
_closeButtonRect = new Rectangle(Width - buttonSize * 0.75f - buttonMargin, buttonMargin, buttonSize * 0.75f, buttonSize * 0.75f);
_colorButtonRect = new Rectangle(_closeButtonRect.Left - buttonSize - buttonMargin, buttonMargin, buttonSize, buttonSize);
_resizeButtonRect = new Rectangle(_closeButtonRect.Left, Height - buttonSize - buttonMargin, buttonSize, buttonSize);
_renameTextBox.Width = Width;
@@ -183,7 +183,7 @@ namespace FlaxEditor.Surface
if (Surface.CanEdit)
{
// Close button
Render2D.DrawSprite(style.Cross, _closeButtonRect, _closeButtonRect.Contains(_mousePosition) && Surface.CanEdit ? style.Foreground : style.ForegroundGrey);
DrawCloseButton(_closeButtonRect, _closeButtonRect.Contains(_mousePosition) && Surface.CanEdit ? style.Foreground : style.ForegroundGrey);
// Color button
Render2D.DrawSprite(style.Settings, _colorButtonRect, _colorButtonRect.Contains(_mousePosition) && Surface.CanEdit ? style.Foreground : style.ForegroundGrey);

View File

@@ -40,6 +40,13 @@ namespace FlaxEditor.Surface
[HideInEditor]
public class SurfaceNode : SurfaceControl
{
internal const float ShadowOffset = 2.25f;
/// <summary>
/// If true, draws a basic rectangle shadow behind the node. Disable to hide shadow or if the node is drawing a custom shadow.
/// </summary>
internal virtual bool DrawBasicShadow => true;
/// <summary>
/// The box to draw a highlight around. Drawing will be skipped if null.
/// </summary>
@@ -55,6 +62,11 @@ namespace FlaxEditor.Surface
/// </summary>
protected Rectangle _headerRect;
/// <summary>
/// The header text rectangle (local space).
/// </summary>
protected Rectangle _headerTextRect;
/// <summary>
/// The close button rectangle (local space).
/// </summary>
@@ -123,7 +135,7 @@ namespace FlaxEditor.Surface
/// <param name="nodeArch">The node archetype.</param>
/// <param name="groupArch">The group archetype.</param>
public SurfaceNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch)
: base(context, nodeArch.Size.X + Constants.NodeMarginX * 2, nodeArch.Size.Y + Constants.NodeMarginY * 2 + Constants.NodeHeaderSize + Constants.NodeFooterSize)
: base(context, nodeArch.Size.X + Constants.NodeMarginX * 2, nodeArch.Size.Y + Constants.NodeMarginY * 2 + Constants.NodeHeaderHeight + Constants.NodeFooterSize)
{
Title = nodeArch.Title;
ID = id;
@@ -132,7 +144,7 @@ namespace FlaxEditor.Surface
AutoFocus = false;
TooltipText = GetTooltip();
CullChildren = false;
BackgroundColor = Style.Current.BackgroundNormal;
BackgroundColor = Color.Lerp(Style.Current.Background, Style.Current.BackgroundHighlighted, 0.55f);
if (Archetype.DefaultValues != null)
{
@@ -147,9 +159,9 @@ namespace FlaxEditor.Surface
public virtual string ContentSearchText => null;
/// <summary>
/// Gets the color of the footer of the node.
/// Gets the color of the header of the node.
/// </summary>
protected virtual Color FooterColor => GroupArchetype.Color;
protected virtual Color ArchetypeColor => GroupArchetype.Color;
private Float2 mouseDownMousePosition;
@@ -161,7 +173,7 @@ namespace FlaxEditor.Surface
/// <returns>The node control total size.</returns>
protected virtual Float2 CalculateNodeSize(float width, float height)
{
return new Float2(width + Constants.NodeMarginX * 2, height + Constants.NodeMarginY * 2 + Constants.NodeHeaderSize + Constants.NodeFooterSize);
return new Float2(width + Constants.NodeMarginX * 2, height + Constants.NodeMarginY * 2 + Constants.NodeHeaderHeight + Constants.NodeFooterSize);
}
/// <summary>
@@ -169,7 +181,7 @@ namespace FlaxEditor.Surface
/// </summary>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
public void Resize(float width, float height)
public virtual void Resize(float width, float height)
{
if (Surface == null)
return;
@@ -187,7 +199,7 @@ namespace FlaxEditor.Surface
{
if (Elements[i] is OutputBox box)
{
box.Location = box.Archetype.Position + new Float2(width, 0);
box.Location = box.Archetype.Position + new Float2(width - Constants.NodeMarginX, 0);
}
}
@@ -215,29 +227,39 @@ namespace FlaxEditor.Surface
var child = Children[i];
if (!child.Visible)
continue;
// Input boxes
if (child is InputBox inputBox)
{
var boxWidth = boxLabelFont.MeasureText(inputBox.Text).X + 20;
if (inputBox.DefaultValueEditor != null)
boxWidth += inputBox.DefaultValueEditor.Width + 4;
leftWidth = Mathf.Max(leftWidth, boxWidth);
leftHeight = Mathf.Max(leftHeight, inputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f);
leftHeight = Mathf.Max(leftHeight, inputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderHeight + 20.0f);
}
// Output boxes
else if (child is OutputBox outputBox)
{
rightWidth = Mathf.Max(rightWidth, boxLabelFont.MeasureText(outputBox.Text).X + 20);
rightHeight = Mathf.Max(rightHeight, outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderSize + 20.0f);
rightHeight = Mathf.Max(rightHeight, outputBox.Archetype.Position.Y - Constants.NodeMarginY - Constants.NodeHeaderHeight + 20.0f);
}
// Elements (Float-, int-, uint- value boxes, asset pickers, etc.)
// These will only ever be on the left side of the node, so we only adjust left width and height
else if (child is SurfaceNodeElementControl elementControl)
{
leftWidth = Mathf.Max(leftWidth, elementControl.Width + 8f);
leftHeight = Mathf.Max(leftHeight, elementControl.Height + 8f);
}
// Other controls in the node
else if (child is Control control)
{
if (control.AnchorPreset == AnchorPresets.TopLeft)
{
width = Mathf.Max(width, control.Right + 4 - Constants.NodeMarginX);
height = Mathf.Max(height, control.Bottom + 4 - Constants.NodeMarginY - Constants.NodeHeaderSize);
width = Mathf.Max(width, control.Right + 15 + Constants.NodeMarginX);
height = Mathf.Max(height, control.Bottom + 4 - Constants.NodeMarginY - Constants.NodeHeaderHeight);
}
else if (!_headerRect.Intersects(control.Bounds))
{
width = Mathf.Max(width, control.Width + 4);
width = Mathf.Max(width, control.Width + 15 + Constants.NodeMarginX);
height = Mathf.Max(height, control.Height + 4);
}
}
@@ -325,6 +347,11 @@ namespace FlaxEditor.Surface
Elements.Add(element);
if (element is Control control)
AddChild(control);
if (!Archetype.UseFixedSize)
ResizeAuto();
else
Resize(Archetype.Size.X, Archetype.Size.Y);
}
/// <summary>
@@ -365,7 +392,7 @@ namespace FlaxEditor.Surface
// Sync properties for exiting box
box.Text = text;
box.CurrentType = type;
box.Y = Constants.NodeMarginY + Constants.NodeHeaderSize + yLevel * Constants.LayoutOffsetY;
box.Y = Constants.NodeMarginY + Constants.NodeHeaderHeight + yLevel * Constants.LayoutOffsetY;
}
// Update box
@@ -434,7 +461,7 @@ namespace FlaxEditor.Surface
private static readonly List<SurfaceNode> UpdateStack = new List<SurfaceNode>();
/// <summary>
/// Updates dependant/independent boxes types.
/// Updates dependent/independent boxes types.
/// </summary>
public void UpdateBoxesTypes()
{
@@ -776,6 +803,24 @@ namespace FlaxEditor.Surface
return output;
}
/// <summary>
/// Draws the close button inside of the <paramref name="rect"/>.
/// </summary>
/// <param name="rect">The rectangle to draw the close button in.</param>
/// <param name="color">The color of the close button.</param>
public void DrawCloseButton(Rectangle rect, Color color)
{
// Disable vertex snapping to reduce artefacts at the line ends
var features = Render2D.Features;
Render2D.Features = features & ~Render2D.RenderingFeatures.VertexSnapping;
rect.Expand(-2f); // Don't overshoot the rectangle because of the thickness
Render2D.DrawLine(rect.TopLeft, rect.BottomRight, color, 2f);
Render2D.DrawLine(rect.BottomLeft, rect.TopRight, color, 2f);
Render2D.Features = features;
}
/// <summary>
/// Draws all the connections between surface objects related to this node.
/// </summary>
@@ -919,6 +964,11 @@ namespace FlaxEditor.Surface
if (Elements[i] is Box box)
box.OnConnectionsChanged();
}
if (!Archetype.UseFixedSize)
ResizeAuto();
else
Resize(Archetype.Size.X, Archetype.Size.Y);
}
/// <inheritdoc />
@@ -956,6 +1006,11 @@ namespace FlaxEditor.Surface
Surface.AddBatchedUndoAction(new EditNodeValuesAction(this, before, graphEdited));
_isDuringValuesEditing = false;
if (!Archetype.UseFixedSize)
ResizeAuto();
else
Resize(Archetype.Size.X, Archetype.Size.Y);
}
/// <summary>
@@ -990,6 +1045,11 @@ namespace FlaxEditor.Surface
}
_isDuringValuesEditing = false;
if (!Archetype.UseFixedSize)
ResizeAuto();
else
Resize(Archetype.Size.X, Archetype.Size.Y);
}
internal void SetIsDuringValuesEditing(bool value)
@@ -998,7 +1058,7 @@ namespace FlaxEditor.Surface
}
/// <summary>
/// Sets teh node values from the given pasted source. Can be overriden to perform validation or custom values processing.
/// Sets teh node values from the given pasted source. Can be overridden to perform validation or custom values processing.
/// </summary>
/// <param name="values">The input values array.</param>
public virtual void SetValuesPaste(object[] values)
@@ -1022,16 +1082,21 @@ namespace FlaxEditor.Surface
public virtual void ConnectionTick(Box box)
{
UpdateBoxesTypes();
if (!Archetype.UseFixedSize)
ResizeAuto();
else
Resize(Archetype.Size.X, Archetype.Size.Y);
}
/// <inheritdoc />
protected override void UpdateRectangles()
{
const float footerSize = Constants.NodeFooterSize;
const float headerSize = Constants.NodeHeaderSize;
const float headerSize = Constants.NodeHeaderHeight;
const float closeButtonMargin = Constants.NodeCloseButtonMargin;
const float closeButtonSize = Constants.NodeCloseButtonSize;
_headerRect = new Rectangle(0, 0, Width, headerSize);
_headerTextRect = _headerRect with { X = 5f, Width = Width - closeButtonSize - closeButtonMargin * 4f };
_closeButtonRect = new Rectangle(Width - closeButtonSize - closeButtonMargin, closeButtonMargin, closeButtonSize, closeButtonSize);
_footerRect = new Rectangle(0, Height - footerSize, Width, footerSize);
}
@@ -1041,8 +1106,16 @@ namespace FlaxEditor.Surface
{
var style = Style.Current;
// Background
var backgroundRect = new Rectangle(Float2.Zero, Size);
// Shadow
if (DrawBasicShadow)
{
var shadowRect = backgroundRect.MakeOffsetted(ShadowOffset);
Render2D.FillRectangle(shadowRect, Color.Black.AlphaMultiplied(0.125f));
}
// Background
Render2D.FillRectangle(backgroundRect, BackgroundColor);
// Breakpoint hit
@@ -1058,18 +1131,18 @@ namespace FlaxEditor.Surface
var headerColor = style.BackgroundHighlighted;
if (_headerRect.Contains(ref _mousePosition) && !Surface.IsConnecting && !Surface.IsSelecting)
headerColor *= 1.07f;
Render2D.FillRectangle(_headerRect, headerColor);
Render2D.DrawText(style.FontLarge, Title, _headerRect, style.Foreground, TextAlignment.Center, TextAlignment.Center);
Render2D.FillRectangle(_headerRect, ArchetypeColor);
Render2D.DrawText(style.FontLarge, Title, _headerTextRect, style.Foreground, TextAlignment.Near, TextAlignment.Center, TextWrapping.NoWrap, 1f, Constants.NodeHeaderTextScale);
// Close button
if ((Archetype.Flags & NodeFlags.NoCloseButton) == 0 && Surface.CanEdit)
{
bool highlightClose = _closeButtonRect.Contains(_mousePosition) && !Surface.IsConnecting && !Surface.IsSelecting;
Render2D.DrawSprite(style.Cross, _closeButtonRect, highlightClose ? style.Foreground : style.ForegroundGrey);
DrawCloseButton(_closeButtonRect, highlightClose ? style.Foreground : style.ForegroundGrey);
}
// Footer
Render2D.FillRectangle(_footerRect, FooterColor);
Render2D.FillRectangle(_footerRect, ArchetypeColor);
DrawChildren();
@@ -1078,7 +1151,7 @@ namespace FlaxEditor.Surface
{
var colorTop = Color.Orange;
var colorBottom = Color.OrangeRed;
Render2D.DrawRectangle(backgroundRect, colorTop, colorTop, colorBottom, colorBottom);
Render2D.DrawRectangle(backgroundRect, colorTop, colorTop, colorBottom, colorBottom, 2.5f);
}
// Breakpoint dot

View File

@@ -2,6 +2,7 @@
using System;
using FlaxEditor.Scripting;
using FlaxEditor.Surface.Elements;
using FlaxEngine;
using FlaxEngine.Utilities;
@@ -140,6 +141,11 @@ namespace FlaxEditor.Surface
/// </summary>
public Texture Background;
/// <summary>
/// The color used as a surface background.
/// </summary>
public Color BackgroundColor;
/// <summary>
/// Boxes drawing callback.
/// </summary>
@@ -216,19 +222,20 @@ namespace FlaxEditor.Surface
private static void DefaultDrawBox(Elements.Box box)
{
var rect = new Rectangle(Float2.Zero, box.Size);
var rect = new Rectangle(box.Width * 0.5f - Constants.BoxSize * 0.5f, box.Height * 0.5f - Constants.BoxSize * 0.5f, new Float2(Constants.BoxSize));
// Size culling
const float minBoxSize = 5.0f;
if (rect.Size.LengthSquared < minBoxSize * minBoxSize)
return;
// Debugging boxes size
// Debugging boxes size and bounds
//Render2D.DrawRectangle(rect, Color.Orange); return;
//Render2D.DrawRectangle(box.Bounds, Color.Green);
// Draw icon
bool hasConnections = box.HasAnyConnection;
float alpha = box.Enabled && box.IsActive ? 1.0f : 0.6f;
float alpha = box.IsDisabled ? 0.6f : 1.0f;
Color color = box.CurrentTypeColor * alpha;
var style = box.Surface.Style;
SpriteHandle icon;
@@ -237,20 +244,37 @@ namespace FlaxEditor.Surface
else
icon = hasConnections ? style.Icons.BoxClose : style.Icons.BoxOpen;
color *= box.ConnectionsHighlightIntensity + 1;
// Disable vertex snapping to prevent position jitter/ snapping artefacts for the boxes when zooming the surface
var features = Render2D.Features;
Render2D.Features = features & ~Render2D.RenderingFeatures.VertexSnapping;
Render2D.DrawSprite(icon, rect, color);
// Draw connected hint with color from connected output box
if (hasConnections && box.Connections[0] is OutputBox connectedOutputBox)
{
bool connectedSameColor = connectedOutputBox.CurrentTypeColor == box.CurrentTypeColor;
Color innerColor = connectedSameColor ? color.RGBMultiplied(0.4f) : connectedOutputBox.CurrentTypeColor;
innerColor = innerColor * alpha;
Render2D.DrawSprite(icon, rect.MakeExpanded(-5.0f), innerColor);
}
// Draw selection hint
if (box.IsSelected)
{
float outlineAlpha = Mathf.Sin(Time.TimeSinceStartup * 4.0f) * 0.5f + 0.5f;
float outlineWidth = Mathf.Lerp(1.5f, 4.0f, outlineAlpha);
var outlineRect = new Rectangle(rect.X - outlineWidth, rect.Y - outlineWidth, rect.Width + outlineWidth * 2, rect.Height + outlineWidth * 2);
Render2D.DrawSprite(icon, outlineRect, FlaxEngine.GUI.Style.Current.BorderSelected.RGBMultiplied(1.0f + outlineAlpha * 0.4f));
Color selectionColor = FlaxEngine.GUI.Style.Current.BorderSelected.RGBMultiplied(1.0f + outlineAlpha * 0.4f);
Render2D.DrawSprite(icon, outlineRect, selectionColor.AlphaMultiplied(0.4f));
}
Render2D.Features = features;
}
/// <summary>
/// Function used to create style for the given surface type. Can be overriden to provide some customization via user plugin.
/// Function used to create style for the given surface type. Can be overridden to provide some customization via user plugin.
/// </summary>
public static Func<Editor, SurfaceStyle> CreateStyleHandler = CreateDefault;
@@ -293,6 +317,7 @@ namespace FlaxEditor.Surface
ArrowClose = editor.Icons.VisjectArrowClosed32,
},
Background = editor.UI.VisjectSurfaceBackground,
BackgroundColor = new Color(31, 31, 31),
};
}
@@ -311,13 +336,11 @@ namespace FlaxEditor.Surface
{
var dir = sub / length;
var arrowRect = new Rectangle(0, 0, 16.0f, 16.0f);
float rotation = Float2.Dot(dir, Float2.UnitY);
if (endPos.X < startPos.X)
rotation = 2 - rotation;
float rotation = Mathf.Atan2(dir.Y, dir.X);
var sprite = Editor.Instance.Icons.VisjectArrowClosed32;
var arrowTransform =
Matrix3x3.Translation2D(-6.5f, -8) *
Matrix3x3.RotationZ(rotation * Mathf.PiOverTwo) *
Matrix3x3.RotationZ(rotation) *
Matrix3x3.Translation2D(endPos - dir * 8);
Render2D.PushTransform(ref arrowTransform);

View File

@@ -65,7 +65,47 @@ namespace FlaxEditor.Surface
/// </summary>
protected virtual void DrawBackground()
{
DrawBackgroundDefault(Style.Background, Width, Height);
DrawBackgroundSolidColor(Style.BackgroundColor, Width, Height);
DrawGridBackground(Width, Height);
}
internal static void DrawBackgroundSolidColor(Color color, float width, float height)
{
Rectangle backgroundRect = new Rectangle(0f, 0f, width, height);
Render2D.FillRectangle(backgroundRect, color);
}
internal void DrawGridBackground(float width, float height)
{
var viewRect = GetClientArea();
var upperLeft = _rootControl.PointFromParent(viewRect.Location);
var bottomRight = _rootControl.PointFromParent(viewRect.Size);
var min = Float2.Min(upperLeft, bottomRight);
var max = Float2.Max(upperLeft, bottomRight);
var pixelRange = (max - min) * ViewScale * 2.75f;
Render2D.PushClip(ref viewRect);
DrawAxis(Float2.UnitX, viewRect, min.X, max.X, pixelRange.X);
DrawAxis(Float2.UnitY, viewRect, min.Y, max.Y, pixelRange.Y);
Render2D.PopClip();
}
private void DrawAxis(Float2 axis, Rectangle viewRect, float min, float max, float pixelRange)
{
var linesColor = Style.BackgroundColor.RGBMultiplied(1.2f);
float[] _gridTickStrengths = { 0f };
Utilities.Utils.DrawCurveTicks((decimal tick, double step, float strength) =>
{
var p = _rootControl.PointToParent(axis * (float)tick); ;
// Draw line
var lineRect = new Rectangle
(
viewRect.Location + (p - 0.5f) * axis,
Float2.Lerp(viewRect.Size, Float2.One, axis)
);
Render2D.FillRectangle(lineRect, linesColor.AlphaMultiplied(strength));
}, Utilities.Utils.CurveTickSteps, ref _gridTickStrengths, min, max, pixelRange);
}
internal static void DrawBackgroundDefault(Texture background, float width, float height)

View File

@@ -217,7 +217,7 @@ namespace FlaxEditor.Surface
set
{
// Clamp
value = Mathf.Clamp(value, 0.05f, 1.6f);
value = Mathf.Clamp(value, 0.05f, 1.85f);
// Check if value will change
if (Mathf.Abs(value - _targetScale) > 0.0001f)

View File

@@ -253,6 +253,16 @@ namespace FlaxEngine
return new Rectangle(Location + new Float2(x, y), Size);
}
/// <summary>
/// Make offseted rectangle
/// </summary>
/// <param name="offset">Offset (will be applied to X- and Y- axis).</param>
/// <returns>Offseted rectangle.</returns>
public Rectangle MakeOffsetted(float offset)
{
return new Rectangle(Location + new Float2(offset, offset), Size);
}
/// <summary>
/// Make offseted rectangle
/// </summary>