Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow Reset Grid Properties for Layout in UI Editor (#1619) #2400

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
using Stride.Core.Quantum;
using Stride.Assets.Presentation.ViewModel;
using Stride.UI;
using System;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: using should be sorted with System.* first

using Stride.UI.Panels;
using static Stride.Rendering.ParameterCollection;

namespace Stride.Assets.Presentation.NodePresenters.Updaters
{
Expand Down Expand Up @@ -141,13 +144,62 @@ private AssetVirtualNodePresenter CreateDependencyPropertyNode(IAssetNodePresent
var propertyContainerNode = ((IObjectNode)accessor.Node)[nameof(UIElement.DependencyProperties)].Target;

var undoRedoService = propertyNodeParent.Asset.ServiceProvider.Get<IUndoRedoService>();

//pass in delegate in the case of VirtualNodePresenters not having proper AssociatedNodes
Func<bool> checkHasBase = null;
Func<object, object> customOverride = null;
UIElement elementNode = SetVirtualNodeDelegates(ref checkHasBase, ref customOverride, property, accessor);

//create virtual node
var virtualNode = node.Factory.CreateVirtualNodePresenter(propertyNodeParent, property.Name, propertyType, order,
() => Getter(propertyContainerNode, propertyIndex),
o => Setter(undoRedoService, propertyContainerNode, propertyIndex, o));
() => Getter(propertyContainerNode, propertyIndex),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: formatting, the previous spacing was correct.

o => Setter(undoRedoService, propertyContainerNode, propertyIndex, o),
checkHasBase, null, null, customOverride);

return virtualNode;
}

/// <summary>
/// Some virutal nodes dont have a specific AssociatedNode that is applicable.
Copy link
Member

@Kryptos-FR Kryptos-FR Sep 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: typo virtual.

/// Instead delegates are passed in the constructor to allow for custom reset behaviors.
///
/// </summary>
/// <param name="property">Current Property Key Object</param>
/// <param name="accessor">Current Node's Accessor Object</param>
/// <param name="checkHasBase">Custom Delegate for if there is base value for ResetOverride in the AssetVirtualNodePresenter</param>
/// <param name="customOverride">Custom Delegate for ResetOverride behavior in the AssetVirtualNodePresenter</param>
/// <returns></returns>
public UIElement SetVirtualNodeDelegates(ref Func<bool> checkHasBase, ref Func<object, object> customOverride, PropertyKey property, NodeAccessor accessor)
{
UIElement elementNode = null;
//TODO: Maybe more optimal ways to verify this property is part of the Universal Grid Properties
if (property.OwnerType.Name == "GridBase" && accessor.Node.Retrieve() is UIElement element)
{
elementNode = element;
customOverride = (input) => CustomResetOverrideGrid(element, property, input);
checkHasBase = () => CustomHasBaseGrid(element, property);
}
return elementNode;
}

//temp place for custom override delegate used on the grid properties, TODO: Find better place for this
public static object CustomResetOverrideGrid(UIElement element, PropertyKey property, object Node)
{
//new default value to set the Node to
int newValue = GridBase.GetBaseValue(property);
var assetVirtualNodePresenter = Node as AssetVirtualNodePresenter;
assetVirtualNodePresenter.UpdateValue(newValue);

return element;
}

//temp place for custom hasBase delegate used on the grid properties, TODO: Find better place for this
// can only enable override for property if the current value isnt the base value
public static bool CustomHasBaseGrid(UIElement element, PropertyKey property)
{
return (int)element.DependencyProperties.Get(property) != GridBase.GetBaseValue(property);
}

/// <summary>
/// Getter for the virtual node's value.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ public AssetNodePresenterFactory([NotNull] INodeBuilder nodeBuilder, [NotNull] I
}

[NotNull]
public AssetVirtualNodePresenter CreateVirtualNodePresenter([NotNull] INodePresenter parent, string name, Type type, int? order, [NotNull] Func<object> getter, Action<object> setter = null, Func<bool> hasBase = null, Func<bool> isInerited = null, Func<bool> isOverridden = null)
public AssetVirtualNodePresenter CreateVirtualNodePresenter([NotNull] INodePresenter parent, string name, Type type, int? order, [NotNull] Func<object> getter, Action<object> setter = null, Func<bool> hasBase = null, Func<bool> isInerited = null, Func<bool> isOverridden = null, Func<object, object> customOverride = null)
{
if (parent == null) throw new ArgumentNullException(nameof(parent));
var node = new AssetVirtualNodePresenter(this, parent.PropertyProvider, parent, name, type, order, getter, setter, hasBase, isInerited, isOverridden);
var node = new AssetVirtualNodePresenter(this, parent.PropertyProvider, parent, name, type, order, getter, setter, hasBase, isInerited, isOverridden, customOverride);
node.ChangeParent(parent);
RunUpdaters(node);
FinalizeTree(node.Root);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
using System;
using Stride.Core.Assets.Editor.Components.Properties;
Expand All @@ -17,12 +17,17 @@ public class AssetVirtualNodePresenter : VirtualNodePresenter, IAssetNodePresent
private readonly Func<bool> isInerited;
private readonly Func<bool> isOverridden;

public AssetVirtualNodePresenter([NotNull] INodePresenterFactoryInternal factory, IPropertyProviderViewModel propertyProvider, [NotNull] INodePresenter parent, string name, Type type, int? order, [NotNull] Func<object> getter, Action<object> setter, Func<bool> hasBase = null, Func<bool> isInerited = null, Func<bool> isOverridden = null)
//Custom Delegate for reset override, when AssociatedNode null
private readonly Func<object, object> customOverride;

public AssetVirtualNodePresenter([NotNull] INodePresenterFactoryInternal factory, IPropertyProviderViewModel propertyProvider, [NotNull] INodePresenter parent, string name, Type type, int? order, [NotNull] Func<object> getter, Action<object> setter, Func<bool> hasBase = null, Func<bool> isInerited = null, Func<bool> isOverridden = null, Func<object, object> customOverride = null)
: base(factory, propertyProvider, parent, name, type, order, getter, setter)
{
this.hasBase = hasBase;
this.isInerited = isInerited;
this.isOverridden = isOverridden;
//custom override for our grid properties
this.customOverride = customOverride;
}

public override void Dispose()
Expand Down Expand Up @@ -71,6 +76,10 @@ public void ResetOverride()

var objectNode = AssociatedNode.Node as IAssetObjectNode;
objectNode?.ResetOverrideRecursively(AssociatedNode.Index);

//use our custom ResetOverride passed in constructor as a delegate
if (customOverride != null)
customOverride(this);
Comment on lines +81 to +82
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer to use the ?.Invoke() pattern, as it's slightly faster.

customOverride?.Invoke(this);

}

private bool IsAssociatedNodeInherited()
Expand Down
52 changes: 52 additions & 0 deletions sources/engine/Stride.UI/Panels/GridBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,57 @@ protected virtual Int3 GetElementGridPositions(UIElement element)
element.DependencyProperties.Get(RowPropertyKey),
element.DependencyProperties.Get(LayerPropertyKey));
}

/// <summary>
/// Gives Property Key lookup based on <see cref="PropertyKey"/>
/// </summary>
/// <param name="propertykey">The property key from which to extract the default value</param>
/// <returns>The default value for propertykey(This would also be the minimum value on the grid.)</returns>
public static PropertyKey<int> GetPropKey(string propKeyName)
{
switch (propKeyName)
{
case "LayerSpanPropertyKey":
return GridBase.LayerSpanPropertyKey;
case "LayerPropertyKey":
return GridBase.LayerPropertyKey;
case "ColumnSpanPropertyKey":
return GridBase.ColumnSpanPropertyKey;
case "ColumnPropertyKey":
return GridBase.ColumnPropertyKey;
case "RowSpanPropertyKey":
return GridBase.RowSpanPropertyKey;
case "RowPropertyKey":
return GridBase.RowPropertyKey;
default:
return null;
}
}

/// <summary>
/// Gives default value based on <see cref="PropertyKey"/>
/// </summary>
/// <param name="propertykey">The property key from which to extract the default value</param>
/// <returns>The default value for propertykey(This would also be the minimum value on the grid.)</returns>
public static int GetBaseValue(PropertyKey propertykey)
{
switch (propertykey.Name)
{
case "LayerSpanPropertyKey":
return 1;
case "LayerPropertyKey":
return 0;
case "ColumnSpanPropertyKey":
return 1;
case "ColumnPropertyKey":
return 0;
case "RowSpanPropertyKey":
return 1;
case "RowPropertyKey":
return 0;
default:
return 0;
}
}
}
}