// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. using FlaxEngine; using FlaxEngine.GUI; namespace FlaxEditor.Surface.Elements { /// /// Bool value element. /// /// [HideInEditor] public sealed class BoolValue : SurfaceNodeElementControl { private bool _mouseDown; /// /// Gets or sets a value. /// public bool Value { get => (bool)ParentNode.Values[Archetype.ValueIndex]; set => ParentNode.SetValue(Archetype.ValueIndex, value); } /// /// Toggle sate /// public void Toggle() { Value = !Value; } /// public BoolValue(SurfaceNode parentNode, NodeElementArchetype archetype) : base(parentNode, archetype, archetype.ActualPosition, new Float2(16), true) { } /// public override void OnSurfaceCanEditChanged(bool canEdit) { base.OnSurfaceCanEditChanged(canEdit); Enabled = canEdit; } /// public override void Draw() { base.Draw(); // Cache data var style = Style.Current; var box = new Rectangle(Float2.Zero, Size); bool value = Value; // Background var backgroundColor = IsMouseOver ? style.TextBoxBackgroundSelected : style.TextBoxBackground; Render2D.FillRectangle(box, backgroundColor); // Border Color borderColor = style.BorderNormal; if (!Enabled) borderColor *= 0.5f; else if (_mouseDown) borderColor = style.BorderSelected; Render2D.DrawRectangle(box, borderColor); // Icon if (value) Render2D.DrawSprite(style.CheckBoxTick, box, Enabled ? style.BorderSelected * 1.2f : style.ForegroundDisabled); } /// public override bool OnMouseDown(Float2 location, MouseButton button) { // Check mouse down if (button == MouseButton.Left) { // Set flag _mouseDown = true; } return base.OnMouseDown(location, button); } /// public override bool OnMouseUp(Float2 location, MouseButton button) { if (_mouseDown && button == MouseButton.Left) { _mouseDown = false; Toggle(); } return base.OnMouseUp(location, button); } /// public override void OnMouseLeave() { // Clear flag _mouseDown = false; base.OnMouseLeave(); } /// /// Gets the boolean value from the specified parent node. Handles type casting and components gather. /// /// The parent node. /// The node element archetype. /// The custom value override (optional). /// The result value. public static bool Get(SurfaceNode parentNode, NodeElementArchetype arch, object customValue = null) { if (arch.ValueIndex < 0 && customValue == null) return false; bool result; var value = customValue ?? parentNode.Values[arch.ValueIndex]; // Note: this value box may edit on component of the vector like Vector3.Y, BoxID from Archetype tells which component pick if (value is bool asBool) { result = asBool; } else if (value is int asInt) { result = asInt != 0; } else if (value is float asFloat) { result = !Mathf.IsZero(asFloat); } else if (value is Vector2 asVector2) { result = !Mathf.IsZero(arch.BoxID == 0 ? asVector2.X : asVector2.Y); } else if (value is Vector3 asVector3) { result = !Mathf.IsZero(arch.BoxID == 0 ? asVector3.X : arch.BoxID == 1 ? asVector3.Y : asVector3.Z); } else if (value is Vector4 asVector4) { result = !Mathf.IsZero(arch.BoxID == 0 ? asVector4.X : arch.BoxID == 1 ? asVector4.Y : arch.BoxID == 2 ? asVector4.Z : asVector4.W); } else { result = false; } return result; } /// /// Sets the boolean value of the specified parent node. Handles type casting and components assignment. /// /// The parent node. /// The node element archetype. /// The value to set. public static void Set(SurfaceNode parentNode, NodeElementArchetype arch, bool toSet) { if (arch.ValueIndex < 0) return; var value = parentNode.Values[arch.ValueIndex]; float toSetF = toSet ? 1.0f : 0.0f; if (value is int) { value = toSet; } else if (value is float) { value = (bool)toSet; } else if (value is Vector2 asVector2) { if (arch.BoxID == 0) asVector2.X = toSetF; else asVector2.Y = toSetF; value = asVector2; } else if (value is Vector3 asVector3) { if (arch.BoxID == 0) asVector3.X = toSetF; else if (arch.BoxID == 1) asVector3.Y = toSetF; else asVector3.Z = toSetF; value = asVector3; } else if (value is Vector4 asVector4) { if (arch.BoxID == 0) asVector4.X = toSetF; else if (arch.BoxID == 1) asVector4.Y = toSetF; else if (arch.BoxID == 2) asVector4.Z = toSetF; else asVector4.W = toSetF; value = asVector4; } else { value = 0; } parentNode.SetValue(arch.ValueIndex, value); } } }