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

Allow resetting VirtualizedDynamicScrollRectList (#540) #541

Merged
merged 14 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from 7 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 @@ -156,6 +156,7 @@ public enum Layout
private float contentStart;
private float layoutPrefabSize;
private bool initialized = false;
private bool resetCalled = false;

private int visibleStart;
private int visibleEnd;
Expand All @@ -164,6 +165,8 @@ public enum Layout
private Queue<GameObject> pool = new Queue<GameObject>();
private Dictionary<int, GameObject> poolDict = new Dictionary<int, GameObject>();

private Action<GameObject, int> onVisible;
private Action<GameObject, int> onInvisible;
#endregion

#region Public properties and fields
Expand All @@ -190,6 +193,24 @@ public float Scroll
}
}

/// <summary>
/// The pool of list item objects will be composed of this Prefab. When
/// the value changes the items are all repopulated.
/// <see cref="ResetLayout"/>
/// </summary>
public GameObject Prefab
{
get => prefab;
set
{
if (prefab != value)
{
prefab = value;
ResetLayout();
}
}
}

/// <summary>
/// This is the current number of items that this list is handling for
/// display.
Expand Down Expand Up @@ -236,18 +257,44 @@ public float Scroll
/// content area, this callback is called, with an integer representing
/// the index of the item in the list. This callback is invoked after
/// the GameObject has been positioned, but just before it is made
/// visible.
/// visible. When the value is set the list of items get reset.
/// <see cref="ResetLayout"/>.
/// </summary>
public Action<GameObject, int> OnVisible { get; set; }
public Action<GameObject, int> OnVisible
{
get => onVisible;
set
{
if (onVisible != value)
{
onVisible = value;
// If this is changeing, it means how the items are populated is changing, hence reset.
ResetLayout();
}
}
}

/// <summary>
/// When a pooled prefab instance is just removed from visibility on
/// the scroll content area, this callback is called, with an integer
/// representing the index of the item in the list. VirtualizedScrollRectList
/// will make this GameObject invisible for you after this callback is
/// invoked.
/// invoked. When the value is set the list of items get reset
/// <see cref="ResetLayout"/>.
/// </summary>
public Action<GameObject, int> OnInvisible { get; set; }
public Action<GameObject, int> OnInvisible
{
get => onInvisible;
set
{
if (onInvisible != value)
{
onInvisible = value;
// If this is changeing, it means how the items are populated is changing, hence reset.
ahmed-shariff marked this conversation as resolved.
Show resolved Hide resolved
ResetLayout();
}
}
}

#endregion

Expand Down Expand Up @@ -313,14 +360,7 @@ private float ScrollToPos(float scroll) => layoutDirection == Layout.Vertical
/// </summary>
private void OnValidate()
{
// We only want to reset things if it has already been initialized,
// we don't want to initialize it prematurely!
if (initialized == false) { return; }

if (margin < gutter) { margin = gutter; }

visibleValid = false;
Initialize();
ResetLayout();
}

/// <summary>
Expand Down Expand Up @@ -394,7 +434,7 @@ private void Initialize()

private void InitializePool()
{
// Support resetting everything from OnValidate
// Support resetting everything from ResetLayout
foreach (int i in poolDict.Keys.ToArray())
{
MakeInvisible(i);
Expand Down Expand Up @@ -484,6 +524,15 @@ private void MakeVisible(int i)
OnVisible?.Invoke(go, i);
}

private IEnumerator ResetLayoutAtEndOfFrame()
{
yield return new WaitForEndOfFrame();
AMollis marked this conversation as resolved.
Show resolved Hide resolved
if (margin < gutter) { margin = gutter; }

resetCalled = false;
visibleValid = false;
Initialize();
}
#endregion

#region Public Methods
Expand Down Expand Up @@ -531,6 +580,27 @@ public void SetItemCount(int newCount)
visibleValid = false;
UpdateScrollView(scroll);
}

/// <summary>
/// Resets the VirtualizedScrollRectList. This may remove items aready
/// visible and create new items.
/// </summary>
public void ResetLayout()
{
// We only want to reset things if it has already been initialized,
// we don't want to initialize it prematurely!
if (initialized == false)
{
return;
}

// We don't want to reset multiple times in one frame.
if (resetCalled)
AMollis marked this conversation as resolved.
Show resolved Hide resolved
{
return;
}
StartCoroutine(ResetLayoutAtEndOfFrame());
}
#endregion
}
}
8 changes: 8 additions & 0 deletions org.mixedrealitytoolkit.uxcore/Tests/Runtime/Prefabs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &8775033607672306323
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4541785853211065393}
- component: {fileID: 5366355943377601298}
- component: {fileID: 6737574300383995924}
m_Layer: 0
m_Name: ScrollTestItem
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &4541785853211065393
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8775033607672306323}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -50, y: 5.550659}
m_SizeDelta: {x: 200, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &5366355943377601298
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8775033607672306323}
m_CullTransparentMesh: 1
--- !u!114 &6737574300383995924
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8775033607672306323}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: New Text
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4294967295
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 36
m_fontSizeBase: 36
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 1
m_VerticalAlignment: 256
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading