Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

New UI Widgets

Discussion in 'Assets and Asset Store' started by ilih, Feb 11, 2015.

  1. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    v1.15.6 released

    Important changes:
    • async support for the dialogs, notifications, pickers
      Code (CSharp):
      1. var result = await PickerTemplate.Clone().ShowAsync(currentValue);
      2. if (result.Success)
      3. {
      4.     currentValue = result;
      5.     Debug.Log("selected value: " + result);
      6. }
      7. else
      8. {
      9.     Debug.Log("canceled");
      10. }
    • Widgets Generator: now you can select the fields that will be used in the widgets, including the field for the autocomplete; it also can be done with [GeneratorIgnore] and [GeneratorAutocomplete] attributes


    Changelog:
    • now the oldest supported version is Unity 2018.4
    • added Grayscale effect
    • added LocalizationSupport option to disable translation for widgets with localization support
    • added LimitMaxSize script to limit size when using anchors stretch
    • added ProgressbarCircular prefab and menu option
    • added SafeArea script to resize RectTransform to fit the safe area
    • added Swipe script
    • Dialog, Notification, Picker: added ShowAsync() method to use with async/await
    • Dialog, Notification, Picker: added IsDestroyed property to check if is instance destroyed
    • Dialog, Notification, Picker: now destroying instances will raise cancel or hide events
    • Effects (derived from UVEffect): improved filled image type support
    • Calendar: add OtherMonthWeekend and OutOfRangeDate colors to the Date component
    • ContextMenu: fixed bug occurring with opened “ContextMenu Items Editor” window in play mode
    • ListView, TreeView: fixed incorrect drop indicator position in some cases
    • ListView: added GetInstanceSize(), SetInstanceSize(), ResetInstanceSize() methods to animate items resize without problems with virtualization
    • ListView: fixed wrong drop position and indicator if enabled CenterTheItems
    • Ring Effect: added Fill option
    • TreeView Drop Support: added AutoDropPosition and DropPosition options
    • TreeView: added AllowToggle option
    • TreeView: added TreeViewToggleAnimation script to animate node toggle
    • Widgets Generator: fixed bug with “const” fields
    • Widgets Generator: now you can select the fields that will be used in the widgets, including the field for the autocomplete; it also can be done with [GeneratorIgnore] and [GeneratorAutocomplete] attributes
     
    Last edited: Jun 19, 2022
    cgrow67 likes this.
  2. seget

    seget

    Joined:
    Dec 17, 2021
    Posts:
    9
    @ilih Hello. I'm trying to collapse all nodes in my hierarchy tree view but it needs a node to be selected to collapse its parents. What I want is when I click on the collapse button, it collapses all nodes without any need of selecting any node. I tried almost everything mostly like selecting nodes from code but I have a very deep and complex hierarchy that there appears a case which it fails. Its like impossible by doing this way. I need a functionality which is going to collapse all. Thanks !
     
  3. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    You can iterate nodes and disable
    node.IsExpanded
    .

    Code (CSharp):
    1.     public class TreeViewCollapse : MonoBehaviour
    2.     {
    3.         [SerializeField]
    4.         public TreeView TreeView;
    5.  
    6.         public void CollapseRoot() // collapse only root nodes
    7.         {
    8.             TreeView.Nodes.BeginUpdate();
    9.  
    10.             foreach (var node in TreeView.Nodes)
    11.             {
    12.                 node.IsExpanded = false; // collapse node
    13.             }
    14.  
    15.             TreeView.Nodes.EndUpdate();
    16.         }
    17.  
    18.         public void CollapseAll() // collapse all nodes
    19.         {
    20.             TreeView.Nodes.BeginUpdate();
    21.             CollapseRecursive(TreeView.Nodes);
    22.             TreeView.Nodes.EndUpdate();
    23.         }
    24.  
    25.         void CollapseRecursive(ObservableList<TreeNode<TreeViewItem>> nodes)
    26.         {
    27.             if (nodes == null)
    28.             {
    29.                 return;
    30.             }
    31.  
    32.             foreach (var node in nodes)
    33.             {
    34.                 node.IsExpanded = false; // collapse node
    35.                 CollapseRecursive(node.Nodes);
    36.             }
    37.         }
    38.     }
     
    Last edited: May 30, 2022
    seget likes this.
  4. seget

    seget

    Joined:
    Dec 17, 2021
    Posts:
    9
    Thanks a lot. :)
     
  5. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,796
    Hi @ilih
    in some cases i want modal area of dialogs to not have color (modalColor:clear) but at the same time clickable so it closes the dialog (im using custom dialog)
    how can i do that
     
  6. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    In case of custom dialog you can override
    SetModal()
    : create a copy of the method and replace one line:
    Code (CSharp):
    1. ModalKey = ModalHelper.Open(this, modalSprite, modalColor, Hide, parentCanvas);
    Or you can create your own modal area:
    Code (CSharp):
    1. var dialog = DialogTemplate.Clone();
    2.  
    3. // create own modal
    4. var canvas = UtilitiesUI.FindTopmostCanvas(dialog.transform);
    5. var modal_key = ModalHelper.Open(dialog, color: Color.clear, onClick: dialog.Hide, parent: canvas);
    6.  
    7. var clicked_button_id = await dialog.ShowAsync(title: "Dialog With Custom Content", buttons: actions, focusButton: "Close");
    8.  
    9. // close modal
    10. ModalHelper.Close(modal_key);
    11.  
    12. // do something depending on the clicked button
    13. ...
    If you use the
    dialog.Show()
    then you need to close modal in buttons callbacks
     
    jGate99 likes this.
  7. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,796
    Hi @ilih
    When a list item is selected, obviously cliciking again on it will not trigger select event, because its already selected.
    But in one case i want to catch this action where item is already selected, and user taps that item again.

    Usecase is:
    I'll have a horizontal list (like tabs) and a vertical list of items
    so when user select an item from horionztal list, then i show 1000 items in vertical list, then user scroll down to middle of 500 items, and now when user click the same selected item, ill scroll user to top

    Please advise
     
  8. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    You can use
    ItemsEvents.PointerClick
    event:
    Code (CSharp):
    1. ListView.ItemsEvents.PointerClick.AddListener(ProcessClick);
    2.  
    3. void ProcessClick(int index, ListViewItem instance, UnityEngine.EventSystems.PointerEventData eventData)
    4. {
    5.     if (ListView.IsSelected(index))
    6.    {
    7.       // click on the selected item, scroll to top
    8.       ListView.ScrollToPositionAnimated(0f);
    9.    }
    10.    else
    11.    {
    12.       // click on not yet selected item, do nothing
    13.    }
    14. }
     
    jGate99 likes this.
  9. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,796
    Hi @ilih
    https://we.tl/t-XJ9qVZnobd

    Please check this video carefully and notice how items vibrate when scrolling is about to end, Every user is complaining about this issue for items with variable height

    I initally thought its Pixel Perfect issue, but it turned out to be something else.

    Please advise
     
  10. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    I'll check what can cause it.
     
    jGate99 likes this.
  11. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    Please try to replace ListView.ScrollRect with the following script:
    Code (CSharp):
    1.     public class ScrollRectWithoutJitter : ScrollRect
    2.     {
    3.         [SerializeField]
    4.         public float PositionThreshold = 0.05f;
    5.  
    6.         protected override void SetContentAnchoredPosition(Vector2 position)
    7.         {
    8.             if (!Vector2Equals(content.anchoredPosition, position, PositionThreshold))
    9.             {
    10.                 base.SetContentAnchoredPosition(position);
    11.             }
    12.         }
    13.  
    14.         static bool Vector2Equals(Vector2 a, Vector2 b, float threshold)
    15.         {
    16.             return (Mathf.Abs(a.x - b.x) <= threshold) && (Mathf.Abs(a.y - b.y) <= threshold);
    17.         }
    18.     }
     
    jGate99 likes this.
  12. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,796
    Hi @ilih
    Any plans for creating a new plugin for UI Toolkit?
     
  13. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    Probably.
    But I doubt that I can be able to work on it until Unity starts making payouts.
     
    jGate99 likes this.
  14. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,796
    You are the best thing that happened to unity ui, and your involvement for ui toolki is must have because all of the mazing things you did for uGui. So i really hope you find a solution to payouts problem.
     
  15. Adunato

    Adunato

    Joined:
    Nov 3, 2018
    Posts:
    28
    Hello, congratulations on this asset, very excited about it.

    I've integrated the Notify components and everything works fine. I'm handling the life-cycle of the notification objects by instantiating with Clone(), saving the instance of the game object, and then destroying it after it's been hidden (will later implement pooling). All good, with the exception of a NotificationReplacement object which is sometime created (I think to support the sliding effect). Is there a way to enable the destruction of these NotificationReplacement objects without changing the code or having to manually fish these objects from the hierarchy?
     
  16. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    Notify already uses built-in pooling (same applied for other widgets with
    Clone()
    method).
    And NotificationReplacement also uses built-in pooling.

    You can use reflection to get access to static field
    NotificationBase.Replacements
    (it is an instances pool of NotificationsReplacement).
    But for what purposes do you need to do that? Probably there is a better way to achieve it.
     
    Last edited: Jun 21, 2022
  17. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,796
    Hi @ilih
    Any idea why im getting this error?
    BTW, it only happens initially and then no errors afterwards

    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. UIWidgets.ScrollRectFooter.GetPosition () (at Assets/New UI Widgets/Scripts/ScrollRectUtilities/ScrollRectFooter.cs:21)
    3. UIWidgets.ScrollRectBlock.Scroll () (at Assets/New UI Widgets/Scripts/ScrollRectUtilities/ScrollRectBlock.cs:290)
    4. UIWidgets.UpdaterProxy.RunOnceActions () (at Assets/New UI Widgets/Scripts/Updater/UpdaterProxy.cs:486)
    5. UIWidgets.UpdaterProxy.Update () (at Assets/New UI Widgets/Scripts/Updater/UpdaterProxy.cs:442)
    6.  

    upload_2022-6-22_13-41-32.png
     
    Last edited: Jun 22, 2022
  18. Adunato

    Adunato

    Joined:
    Nov 3, 2018
    Posts:
    28
    There is just me setting the expectation bar too low :) My bad, I didn't realise there was built-in pool. I am now even more impressed :)
     
  19. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    Try to add
    Init()
    call in
    OnEnable()
    method at New UI Widgets / Scripts / ScrollRectUtilities / ScrollBlock.cs.
    Code (CSharp):
    1.         protected virtual void OnEnable()
    2.         {
    3.             Init();
    4.             Updater.RunOnceNextFrame(Scroll);
    5.         }
     
    jGate99 likes this.
  20. DavidLe360

    DavidLe360

    Joined:
    Dec 24, 2018
    Posts:
    127
    Hi,
    - Q1: is there a way to know the column number of a table's cell?
    - Q2: is it possible to have a table with dynamic columns: numbers of columns will be appended dynamically, like the rows.

    Hope my questions make sense :D
     
  21. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    There are two column numbers:
    • index in the current column order:
      var current_position = cell.transform.GetSiblingIndex();
    • index in the original column order:
      var original_position = TableHeader.GetColumnsOrder().IndexOf(current_position);
    Original column order should be used if
    TableHeader.AllowReorder
    enabled.

    Yes, it is possible.
    You can check the demo scene and scripts in the Examples / Table / TableList folder.
     
    Last edited: Jun 23, 2022
    DavidLe360 likes this.
  22. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,796
    Hi @ilih
    How do i get access to modal for a dialog?
    Currently I wanted to set layer for modal to "ui" and i had to make this change in the
    ModalHelper.Open
    function directly which is not a good solution
    please advise
     
  23. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    You can override
    Dialog.SetModal()
    method (it should be possible in the latest beta, not sure about earlier versions):
    Code (CSharp):
    1.         public override void SetModal(bool modal = false, Sprite modalSprite = null, Color? modalColor = null, RectTransform parentCanvas = null)
    2.         {
    3.             base.SetModal(modal, modalSprite, modalColor, parentCanvas);
    4.  
    5.             if (ModalKey != null)
    6.             {
    7.                 var instance = ModalHelper.GetInstance(ModalKey.Value);
    8.                 instance.gameObject.layer = LayerMask.NameToLayer("UI");
    9.             }
    10.         }
     
    jGate99 likes this.
  24. goyaniharsh3939

    goyaniharsh3939

    Joined:
    Apr 20, 2020
    Posts:
    3
    what is a good way to add item in autocomplete combo box, and remove all the item listed there at once(In runtime). I tried to read document for whole day but didn't find any solution. Any help will be appreciated. Thankyou
     
  25. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    AutocompleteCombobox is a simple wrapper for Autocomplete with a button to show a list (by default list is displayed only on typing), so you need to use the
    Autocomplete
    property.

    Code (CSharp):
    1. [SerializeField]
    2. public AutocompleteStringCombobox AutocompleteCombobox;
    3.  
    4. // ...
    5.  
    6. AutocompleteCombobox.Autocomplete.InputFieldAdapter.text = ""; // clear input
    7. AutocompleteCombobox.Autocomplete.DataSource.Clear(); // remove all items
    8. AutocompleteCombobox.Autocomplete.DataSource.Add("new item"); // add new item
    or use reference to
    Autocomplete
    itself.
    Code (CSharp):
    1. [SerializeField]
    2. public AutocompleteString Autocomplete;
    3.  
    4. // ...
    5.  
    6. Autocomplete.InputFieldAdapter.text = ""; // clear input
    7. Autocomplete.DataSource.Clear(); // remove all items
    8. Autocomplete.DataSource.Add("new item"); // add new item
    Difference between AutocompleteCombobox and AutoCombobox:
    AutocompleteCombobox basically is InputField with autocomplete feature, so you can get only string, not selected item.
    AutoCombobox is Combobox with the option to select items by typing, with it you can get selected items.
     
    goyaniharsh3939 likes this.
  26. RickSaada1

    RickSaada1

    Joined:
    Mar 9, 2015
    Posts:
    15
    I'm currently using 1.14.2 and I've hit a what I think is a bug in ComboboxString. The short version is that if you try and reinitialize a combo a second time after you've had an item selected in it, things crash because Clear() doesn't clear the previously selected indices. In my case, it tries to access item 4 in the list which now has 0 items in it while in the middle of the UpdateView(); call at the end of ComboboxCustom.Clear().

    As best I can tell reading the code, the SelectedItemsCache in ListViewCustom, and the selectedIndices in ListViewBase are both not cleaned up properly on Clear(). I've added code in my version to do this, but I don't know if the problem still exists in the current build.
     
  27. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    Thanks, the bug happens because deselect events are not raised when the list is cleared.
    Workaround:
    add the line
    DeselectAll();
    to the
    Clear()
    method in New UI Widgets / Scripts / ListView / ListViewCustom.cs
    Code (CSharp):
    1. public override void Clear()
    2. {
    3.    DeselectAll();
    4.    DataSource.Clear();
    5.    ListRenderer.SetPosition(0f);
    6. }
    I am working on a proper fix.
     
    RickSaada1 likes this.
  28. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,796
    Hi @ilih
    In what cases this method triggers?
    upload_2022-8-5_0-40-26.png
     
  29. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    During navigation with keyboard or gamepad:
    when the item instance in the ListView is under focus (selected by EventSystem) and pressed any arrow button or gamepad stick or d-pad (it is default settings, exact settings should be checked with InputModule component at EventSystem game object).
     
  30. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,796
    how do i disable it on mobile? because there will be no keyboard on mobile
     
  31. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    You can disable ListView.Navigation then navigation events will be ignored.
    Another option is to completely disable Navigation using the component EventSystem game object:
    if Standalone Input System: rename Horizontal Axis and Vertical Axis to the unspecified axis (axises list in Projects Settings / Input Manager)
    if Input System UI Input Module: change Move to None
    upload_2022-8-5_15-21-1.png
    upload_2022-8-5_15-23-28.png
     
    jGate99 likes this.
  32. KiraSnow

    KiraSnow

    Joined:
    Feb 22, 2021
    Posts:
    20
    how to fix the bug of when i use ListView and use mouse to hovel an item, the "highlight of current selection" always go upward and move my scroll view ?
     
  33. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    The most probable cause is a drift of the gamepad stick, a joystick that is not in a neutral position, or any other controller.
    You can check it by disabling ListView.Navigation, if the highlight stops going moving automatically then it is a cause. (Gamepad/joystick/keyboard arrows inputs are treated as navigation events and move focus to the nearest or specified item in the movement direction.)

    Solutions (excluding replacing or disconnecting the controller):
    For the legacy Input (Project Settings / Input Manager):
    • increase
      Dead
      zone option to avoid stick's drift or set
      Sensitivity
      to 0 to disable input completely for the Horizontal and Vertical axes (there is more than one record for each axis, you need to change the correct one)
    • create a new axis with
      Sensitivity
      = 0 and specify that axis in
      Standalone Input System
      component as Horizontal Axis and Vertical Axis
    For the Input System (Project Settings / Input System Package):
    • specify supported devices to exclude problem controller
     
  34. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    v1.15.7 released

    Changelog:
    • added LoadAnimation widget
    • Dialog, Lightbox, Picker, Popup: added HideOnModalClick option
    • added workaround to avoid ReSharper RRSRP-489023 bug
    • Combobox: fixed bug when items were removed but still displayed as selected
    • ListView: added ChangeLayoutType option: if enabled changes EasyLayout.LayoutType to match ListType.
    • ListView, TreeView: now the deselect events invoked for the removed indices/nodes
     
  35. DavidLe360

    DavidLe360

    Joined:
    Dec 24, 2018
    Posts:
    127
    Hi, how to dynamically (by code) change TableHeader column width? My goal is to change to size of the column's widths, by code or by entering it in the inspector.

    I tried to changed the values of LayoutElement's PreferredWidth on the inspector, but at runtime that values are modified by some code. So I look at the class
    TableHeader
    , in the method
    OnBeginDrag
    , I found this part of code seems interesting though:
    Code (CSharp):
    1.                         var left_cell = GetCellInfo(left);
    2.                         leftTarget = left_cell.LayoutElement;
    3.                         rightTarget = cell.LayoutElement;
    4.  
    5.                         leftTargetWidth = left_cell.Width;
    6.                         rightTargetWidth = cell.Width;
     
  36. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    Add the following code to the New UI Widgets / Scripts / Table / TableHeader.cs
    Code (CSharp):
    1.  
    2.         /// <summary>
    3.         /// Set column width.
    4.         /// </summary>
    5.         /// <param name="column">Column index in the displayed order (not the original one).</param>
    6.         /// <param name="width">Width.</param>
    7.         /// <param name="resizeRightNeighbour">Resize column width on the right or on the left.</param>
    8.         public void SetColumnWidth(int column, float width, bool resizeRightNeighbour = true)
    9.         {
    10.             if (column == (CellsInfo.Count - 1) && resizeRightNeighbour)
    11.             {
    12.                 resizeRightNeighbour = false;
    13.             }
    14.             else if (column == 0 && !resizeRightNeighbour)
    15.             {
    16.                 resizeRightNeighbour = true;
    17.             }
    18.  
    19.             var left = GetCellInfo(resizeRightNeighbour ? column : column - 1);
    20.             var right = GetCellInfo(resizeRightNeighbour ? column + 1 : column);
    21.             var total = left.Width + right.Width;
    22.  
    23.             if (resizeRightNeighbour)
    24.             {
    25.                 left.LayoutElement.preferredWidth = Mathf.Min(width, total - right.LayoutElement.minWidth);
    26.                 right.LayoutElement.preferredWidth = total - left.LayoutElement.preferredWidth;
    27.             }
    28.             else
    29.             {
    30.                 right.LayoutElement.preferredWidth = Mathf.Min(width, total - left.LayoutElement.minWidth);
    31.                 left.LayoutElement.preferredWidth = total - right.LayoutElement.preferredWidth;
    32.             }
    33.  
    34.             LayoutUtilities.UpdateLayout(layout);
    35.             Resize();
    36.         }
     
    Last edited: Aug 16, 2022
    DavidLe360 likes this.
  37. Petskus

    Petskus

    Joined:
    Jan 29, 2019
    Posts:
    25
    Such exceptions started appearing in my project

    EasyLayoutNS.EasyLayoutBaseType.SetElementsSize (EasyLayoutNS.ResizeType resizeType) (at Assets/New UI Widgets/Scripts/EasyLayout/EasyLayoutBaseType.cs:551)
    EasyLayoutNS.EasyLayoutBaseType.PerformLayout (System.Collections.Generic.List`1[T] elements, System.Boolean setPositions, EasyLayoutNS.ResizeType resizeType) (at Assets/New UI Widgets/Scripts/EasyLayout/EasyLayoutBaseType.cs:448)
    EasyLayoutNS.EasyLayout.PerformLayout (System.Boolean setPositions, EasyLayoutNS.ResizeType resizeType) (at Assets/New UI Widgets/Scripts/EasyLayout/EasyLayout.cs:1503)
    EasyLayoutNS.EasyLayout.SetLayoutHorizontal () (at Assets/New UI Widgets/Scripts/EasyLayout/EasyLayout.cs:1292)
    UnityEngine.UI.LayoutRebuilder+<>c.<Rebuild>b__12_1 (UnityEngine.Component e) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Layout/LayoutRebuilder.cs:86)
    UnityEngine.UI.LayoutRebuilder.PerformLayoutControl (UnityEngine.RectTransform rect, UnityEngine.Events.UnityAction`1[T0] action) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Layout/LayoutRebuilder.cs:128)
    UnityEngine.UI.LayoutRebuilder.Rebuild (UnityEngine.UI.CanvasUpdate executing) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Layout/LayoutRebuilder.cs:86)
    UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate (UnityEngine.RectTransform layoutRoot) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Layout/LayoutRebuilder.cs:72)
    UnityEngine.UI.ScrollRect.SetLayoutHorizontal () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/ScrollRect.cs:1173)
    UnityEngine.UI.LayoutRebuilder+<>c.<Rebuild>b__12_1 (UnityEngine.Component e) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Layout/LayoutRebuilder.cs:86)
    UnityEngine.UI.LayoutRebuilder.PerformLayoutControl (UnityEngine.RectTransform rect, UnityEngine.Events.UnityAction`1[T0] action) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Layout/LayoutRebuilder.cs:124)
    UnityEngine.UI.LayoutRebuilder.PerformLayoutControl (UnityEngine.RectTransform rect, UnityEngine.Events.UnityAction`1[T0] action) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Layout/LayoutRebuilder.cs:133)
    UnityEngine.UI.LayoutRebuilder.Rebuild (UnityEngine.UI.CanvasUpdate executing) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Layout/LayoutRebuilder.cs:86)
    UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate (UnityEngine.RectTransform layoutRoot) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Layout/LayoutRebuilder.cs:72)
    UnityEngine.UI.ScrollRect.SetLayoutHorizontal () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/ScrollRect.cs:1173)
    UnityEngine.UI.LayoutRebuilder+<>c.<Rebuild>b__12_1 (UnityEngine.Component e) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Layout/LayoutRebuilder.cs:86)
    UnityEngine.UI.LayoutRebuilder.PerformLayoutControl (UnityEngine.RectTransform rect, UnityEngine.Events.UnityAction`1[T0] action) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Layout/LayoutRebuilder.cs:124)
    UnityEngine.UI.LayoutRebuilder.Rebuild (UnityEngine.UI.CanvasUpdate executing) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Layout/LayoutRebuilder.cs:86)
    UnityEngine.UI.CanvasUpdateRegistry.PerformUpdate () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/CanvasUpdateRegistry.cs:181)
    UnityEngine.UI.InputField:OnEnable() (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/InputField.cs:1154)

    Replacing "foreach" by "for" in EasyLayoutBaseType.cs eliminated them

    Code (CSharp):
    1.  
    2.      protected void SetElementsSize(ResizeType resizeType)
    3.         {
    4.             // foreach (var element in ElementsGroup.Elements)
    5.             for (int i = 0; i < ElementsGroup.Elements.Count; i++)
    6.             {
    7.                 var element = ElementsGroup.Elements[i];
    8.                 SetElementSize(element, resizeType);
    9.                 OnElementChangedInvoke(element.Rect, DrivenProperties);
    10.             }
    11.         }
    12.  
     
  38. Gladyon

    Gladyon

    Joined:
    Sep 10, 2015
    Posts:
    386
    Not sure that it's the best solution.
    You're hiding the symptoms of the problem instead of fixing the root of the problem.

    Either you're playing with multi-threading, in which case you may still have an exception, if you enter the loop and just before the access to the Elements array an element is removed, and if by chance you were looping for the last element, then it will throw (won't happen often, but it will happen).
    Fixing the problem here would require to know how/why/when the elements can be accessed by the other thread(s).

    Either you are removing an element in 'OnElementChangeInvoke()' (which is the best candidate I'd say), which is probably not a good idea as the very same problem could happen in another similar loop modifying the elements.
    You could mark the element as to be removed, and then remove all the marked elements when it's safe, perhaps in some 'Update()'.

    Theoretically, it could also happen in 'SetElementSize()', but I doubt it, it would be really strange and probably not a good omen if an element was removed there.
    Anyway, marking and then removing would also work in that case.
     
  39. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    Are there any other errors like "Trying to add ... for graphic rebuild while we are already inside a graphic rebuild loop. This is not supported."?
    Or probably something related to the ResizeListener or ScrollRectContentResize.

    Better fix it this way:
    Code (CSharp):
    1.         List<LayoutElementInfo> resizedElements = new List<LayoutElementInfo>();
    2.  
    3.         protected void SetElementsSize(ResizeType resizeType)
    4.         {
    5.             resizedElements.AddRange(ElementsGroup.Elements);
    6.  
    7.             foreach (var element in resizedElements)
    8.             {
    9.                 SetElementSize(element, resizeType);
    10.                 OnElementChangedInvoke(element.Rect, DrivenProperties);
    11.             }
    12.  
    13.             resizedElements.Clear();
    14.         }
     
  40. Petskus

    Petskus

    Joined:
    Jan 29, 2019
    Posts:
    25
    No :(
     
  41. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    Is the problem happening on the demo scene or with some widget?
    And what Unity version are you using?
     
  42. MarcOrion

    MarcOrion

    Joined:
    Nov 27, 2014
    Posts:
    14
    Disregard. I found the issue.
     
    Last edited: Aug 28, 2022
    ilih likes this.
  43. MarcOrion

    MarcOrion

    Joined:
    Nov 27, 2014
    Posts:
    14
    Tree.SelectedIndex always returns -1.

    How to get the selected item in the tree view at runtime?
     
  44. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    Maybe you are trying to get the selected index from the wrong TreeView.
    Try this:
    Code (CSharp):
    1. TreeView.Select(0);
    2. Debug.Log(TreeView.SelectedIndex); // should be 0 and fist node should be displayed as selected
    Is the node displayed as selected?
    Node selected from UI interaction or from code?
    If you specified
    TreeView.CanSelect
    function then it can dissalow selection.
     
  45. MarcOrion

    MarcOrion

    Joined:
    Nov 27, 2014
    Posts:
    14
    Only have one treeview in the scene.

    It seems to be working now. had something to do with the defaultItem toggle on click being unchecked. When I checked it things work as expected. This is very unintuitive. I originally unchecked it because I dont want multiselect. Now I uncheck the previously checked item programmatically to enforce single selection.
     
  46. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    I'll think about a better name for this option, at least it has a proper tooltip.
    upload_2022-8-29_3-48-37.png

    You can disable the
    Multiple Select
    option instead of deselecting previous items from the code. upload_2022-8-29_3-47-5.png
     
  47. MarcOrion

    MarcOrion

    Joined:
    Nov 27, 2014
    Posts:
    14
    I have been trying to make use of this asset but the more I get into it the more frustrated I get.

    Things just do not work as expected. I will give two good examples: The fileDialog and the DatePicker.

    I added a datePicker to my scene and enabled it at run time. Looks good, however, all I can do is click on dates. That’s it. There is only a cancel button. No select or save date button. Worse is when you click cancel (or the little “X” at the top) you get an ArgumentNullException: Value cannot be null. This is a simple widget and should work right out of the box. I should be able to select a date and the widget stores it for me to use in code somewhere. I am not trying to do anything fancy with it, simply select a date and have it passed to me for my own use in code. This should work right out of the box. It doesn’t.

    The fileDialog is even worse. Not only does it have multiple null reference exceptions while using it, it also does not save the file name/location so I can use it elsewhere in code (the Ok button does nothing). It has also crashed my editor several times. Again, this is a simple widget. If you add it to a scene, enable it, navigate to the folder you want and select the file that you want and click OK, it should actually passes you the file location in code so that you can do something with it. This should be out of the box functionality. If I have to go in and make the OK button do what I expect it to do (complete the file selection process and pass me the file location and name) then I might as well roll my own solution. Also shouldn’t be getting several null ref exceptions while navigating folders in the fileDialog window. Not acceptable.

    I know that a lot of work has been put into this asset and that it offers a lot, but at a minimum the out of the box functionality should work as expected. What is the use of offering a file dialog widget or date picker widget that only goes halfway to doing what you expect it to do?

    I don’t want to leave a negative review which is why I am here on the forum seeking help. I admit that maybe I am missing something here. As I mentioned before in another post, there are many things that are not very intuitive at all. As the creator you are very close to the asset, you know it intimately, so things might make perfect sense to you. As an end user, I can only take it for what it is. If a datepicker lets you pick a date, I expect that when I select that date and click ok (there is no OK button by the way) that the date is available in code for me to work with. What I don’t expect is to start banging my head against the wall looking for an OK button.
     
  48. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    The pickers are intended to use from code.
    DatePicker (FilePicker has similar usage):
    Code (CSharp):
    1.         [SerializeField]
    2.         protected DatePicker PickerTemplate;
    3.  
    4.         DateTime currentValue = DateTime.Today;
    5.  
    6.         public async void Test()
    7.         {
    8.             // create picker from template
    9.             var picker = PickerTemplate.Clone();
    10.  
    11.             // show picker
    12.             var value = await picker.ShowAsync(currentValue);
    13.             if (value.Success)
    14.             {
    15.                 currentValue = value;
    16.                 Debug.Log(string.Format("value: {0}", value.ToString()));
    17.             }
    18.             else
    19.             {
    20.                 Debug.Log("canceled");
    21.             }
    22.         }
    It's covered in the documentation: DatePicker, FilePicker.
    If you want to just select a date or file then you can use Calendar and FileListView.

    You can check the New UI Widgets / Examples / Calendar / Calendar scene to check how to use both Calendar and DatePicker and New UI Widgets / Examples / IO / FileListView+FileDialog for similar purpose.

    Most of the things are covered in the documentation or have separate demo scenes (not the huge main scene) with scripts (if such scripts are necessary).

    What Unity version are you using?
    Those errors may be from missing references in a prefab (such things happen in Unity when updating to a newer version and despite all my checks it goes to release) or it can be because the prefab gameobject was just enabled instead of activating it from code.
     
    Last edited: Aug 29, 2022
  49. MarcOrion

    MarcOrion

    Joined:
    Nov 27, 2014
    Posts:
    14

    Thank you for the quick replies and the help provided. I am using unity 2020.3.37. I will try as you mentioned above tomorrow as it is late and I am tired, but again, if I right click->create->UI->New UIWidget->DatePicker, the inserted widget should work. It doesnt make sense that there is no OK button to finish selecting the date. I hope that makes sense.
     
  50. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    1,278
    1. About error:
    add lines to the
    ToCache()
    method in New UI Widgets / Scripts / Templates.cs after line
    instance.gameObject.SetActive(false);

    Code (CSharp):
    1.             instance.gameObject.SetActive(false);
    2.             // added lines
    3.             if (instance.TemplateName == null)
    4.             {
    5.                 return;
    6.             }
    2. I'll think about what to do with Pickers (also Dialogs and Notifications) because they should be used from code, they are not intended to be just enabled without proper configuration.
    Maybe I'll add functionality to imitate expected behavior in such cases, maybe rename the menu category to make clear that they cannot be used right away to avoid misunderstandings, or maybe just completely remove them from the menu (scripts will use references on prefab instead of a gameobject on the scene).

    If the date is selected then DatePicker returns that date and closes itself (if there is nobody to receive the selected date then do nothing), so there is no need for the OK button.
    From my side: I already clicked to select the date, why do I need to click a more button?

    In the next update, I'll add an option to toggle between the current behavior and the OK button.