Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

New UI Widgets

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

  1. cgrow67

    cgrow67

    Joined:
    May 31, 2016
    Posts:
    20
    Would it be possible to move your extension methods for System types into their own namespace?
    Something like UIWidgets.SystemExtensions ?

    The reason I ask is because ... well I guess great minds think alike.
    I frequently get errors like this.

    The call is ambiguous between the following methods or properties: 'UIWidgets.Extensions.ForEach<T>(System.Collections.Generic.IEnumerable<T>, System.Action<T>)' and 'Sage.Designer.Unity.Extensions.IEnumerableExtension.ForEach<TValue>(System.Collections.Generic.IEnumerable<TValue>, System.Action<TValue>)'

    If you moved your System extensions into a separate namespace they are still usable with a simple using.
    it will let me bring everything in but them and use my extension methods for System types.

    I know this is nit picky.. I was just hoping in a future release this might get this addressed.
     
  2. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    OK, I'll fix it in the next release.
     
    cgrow67 likes this.
  3. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    Added ListView.ItemsEvents field with items events in v1.12.5f1.

    Extension methods moved to UIWidgets.Extensions namespace.

    v1.12.5f1 already submitted to Assetstore and will be available after approval.
     
    cgrow67 and jGate99 like this.
  4. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,246
    Can you please explain this ItemsEvent field? and what are the use cases?
     
  5. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    With the ItemsEvents field, you can easily add listeners to item events: like pointer enter, pointer exit, click, and others.

    For example, replace items on double click like it's done in FileListView.

    In the previous version to process double click outside DefaultIem, you need to modify the item component code (or create a new class):
    Code (CSharp):
    1. public class ListViewItemComponent : ....
    2. {
    3.         public void DoubleClick()
    4.         {
    5.             (Owner as ListViewType).ProcessDoubleClick(Index);
    6.         }
    7. }
    Either way is modify ListView code:
    Code (CSharp):
    1.  
    2.         protected virtual void ProcessDoubleClick(int index)
    3.         {
    4.             this.onDoubleClick.Invoke( index );        
    5.         }
    6.         protected override void AddCallback(ListViewItem item)
    7.         {
    8.             base.AddCallback(item);
    9.             item.onDoubleClick.AddListener(ProcessDoubleClick);
    10.         }
    11.         protected override void RemoveCallback(ListViewItem item)
    12.         {
    13.             if (item == null)
    14.             {
    15.                 return;
    16.             }
    17.             base.RemoveCallback(item);
    18.             item.onDoubleClick.RemoveListener(ProcessDoubleClick);
    19.         }
    Now you can simply add listener for the required events without code changes:
    Code (CSharp):
    1. ListView.ItemsEvents.DoubleClick.AddListener(ProcessDoubleClick);
     
    jGate99 likes this.
  6. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,246
    Amazing Update.
     
  7. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,246
    Hi @ilih

    I'm having trouble making a list view with multi select enable, where it only selects/deselct an item if user clicks on a "given" area (in my case right area)
    w.png
    Please advise
    Thanks
     
  8. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    1. You need to disable item select/deselect on click/submit: override OnPointerClick and OnSubmit to remove onClickItem and onSubmit events invocation in your DefaultItem class
      Code (CSharp):
      1.         public override void OnPointerClick(UnityEngine.EventSystems.PointerEventData eventData)
      2.         {
      3.             if (!IsInteractable())
      4.             {
      5.                 return;
      6.             }
      7.  
      8.             onPointerClick.Invoke(eventData);
      9.  
      10.             if (AllowItemsEvents())
      11.             {
      12.                 Owner.ItemsEvents.PointerClick.Invoke(Index, this, eventData);
      13.             }
      14.  
      15.             if ((eventData.button == UnityEngine.EventSystems.PointerEventData.InputButton.Left) && (eventData.clickCount == 1))
      16.             {
      17.                 #pragma warning disable 0618
      18.                 onClick.Invoke();
      19.                 #pragma warning restore 0618
      20.  
      21.                 if (Owner != null)
      22.                 {
      23.                     Owner.ItemsEvents.FirstClick.Invoke(Index, this, eventData);
      24.                 }
      25.  
      26.                 Select();
      27.             }
      28.  
      29.             if ((eventData.button == UnityEngine.EventSystems.PointerEventData.InputButton.Left) && (eventData.clickCount == 2))
      30.             {
      31.                 onDoubleClick.Invoke(Index);
      32.                 if (AllowItemsEvents())
      33.                 {
      34.                     Owner.ItemsEvents.DoubleClick.Invoke(Index, this, eventData);
      35.                 }
      36.             }
      37.         }
      38.  
      39.         public override void OnSubmit(UnityEngine.EventSystems.BaseEventData eventData)
      40.         {
      41.             if (!IsInteractable())
      42.             {
      43.                 return;
      44.             }
      45.  
      46.             if (AllowItemsEvents())
      47.             {
      48.                 Owner.ItemsEvents.Submit.Invoke(Index, this, eventData);
      49.             }
      50.         }
    2. Add code to select/deselect item on Toggle change
      Code (CSharp):
      1.         [SerializeField]
      2.         public Toggle SelectToggle;
      3.  
      4.         // add SelectToggle.onValueChanged listener in code or inspector window
      5.         public void ToggleChange()
      6.         {
      7.             if (SelectToggle.isOn)
      8.             {
      9.                 Owner.Select(Index);
      10.             }
      11.             else
      12.             {
      13.                 Owner.Deselect(Index);
      14.             }
      15.         }
     
    jGate99 likes this.
  9. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    v1.12.5f1 available

    Changelog:
    • added UIFlareGlobal shader: flare at global space
    • added Ripple effect
    • UIWidgets extensions methods moved to UIWidgets.Extensions namespace
    • EasyLayout extensions methods moved to EasyLayoutNS.Extensions namespace
    • shaders: replaced properties names with properties IDs
    • Dialog: Show() arguments can later be changed with other methods: SetInfo(), SetButtons(), FocusButton(), SetPosition(), SetContent(), SetCanvas(), SetModal().
    • EasyLayout: added GetElementPosition to get position in group
    • InputFieldExtended: fixed bug with Value property (thanks to RickSaada1)
    • ListView: added ItemsEvents field
    • ListViewItem: now foreground and background graphics are serialized properties
    • Notify: added buttons support with SetButtons(IList<DialogButton> buttons) method
    • ProgressbarIndeterminate: fixed bar jump at the start
    • TableHeader: fixed bug with ColumnToggle (thanks to jbw)
    • UIFlare shaders: added flare delay property
     
    cgrow67 and hopeful like this.
  10. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,246
    this way in future if there is change in base class then this custom code will not be accurate.
    Sot, It'd be great for Step 1 if you can add this behavour in base class by setting a boolean. Like SelectionMode = Manual/Auto

    like if(Owner.SelectionMode == Auto){
    onClickItem.invoke
    }

    For Step 2, we can do that ourselve as its just calling owner .select or deselct.

    Thanks
     
    Last edited: Nov 18, 2020
  11. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,246
    BTW, I used a button instead of Toggle,
    And Simply Call Select/Deslect

    Which works, but other items dont get deselected even if i call updateItems()

    I thought Calling Owner.Select(index) on List view will automaticlly deselect other indeces if multi select is disabeld


    UPDATE 3
    Please provide a sample that works, and can be used for both as a radio list and as a check box list behavoir.
    As im constantly failing to make it work

    PS: I actually want same list to behave multi select (as checbox) and then multi select off (as radio)

    A sample scene that does that and have selection trigger on right side'd b hugely appreciated.

    Thaanks
     
    Last edited: Nov 18, 2020
  12. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    Yes, other indices will be deselected, but you need some code to redraw the selection indicatior.

    Added example in v1.12.6b1
    ListViewCheckbox scene and ListViewIconsToggleComponent script at "Examples / ListView / ListViewCheckbox" folder
     
    jGate99 likes this.
  13. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,246
    Let me check right away, Thanks
     
  14. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,246
    Just to be sure,
    This works with both Multi Select On (in that case it will work as checkboxes) and Multi Select Off (in that case as Radio)

    Because it seems to be wroking that way and i want to confirm
     
  15. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    Yes, with both MultiSelect on and off.
     
    jGate99 likes this.
  16. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,246
    Amazing, Thanks for quick update.
     
  17. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    You need to get index of the node and then select index - 1.
    Code (CSharp):
    1.             var index = Tree.Node2Index(node);
    2.             Tree.Select(index - 1); // select previous
    3.             node.Parent = null; // remove node
    or you if node selected then you can simply use
    Tree.Select(Tree.SelectedIndex - 1);
     
  18. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,246
    Hi @ilih
    If i set DataSource and then in less than a second call Updateitems, then first visual item disappears unless i start scrolling and then it appears back immediatly.
    Please advise
     
  19. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    What ListType is specified in the ListView settings?
     
    jGate99 likes this.
  20. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,246
    Its ListView with variable size.
     
  21. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    Please check is the first item disappears if replace
    UpdateItems()
    with
    UpdateView()
    .
    I can't reproduce the bug, so it helps narrow down the source of the problem.

    The scene with the script to reproduce the bug will be great.
     
    jGate99 likes this.
  22. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,246
    Hi ilih, i finallly found the issue and solution to solve it
    Problem was not with updateItems but rather not having a layout item with min height, now everythingg seems great
    Thanks
     
    ilih likes this.
  23. Qusdrok

    Qusdrok

    Joined:
    Jun 28, 2020
    Posts:
    19
    hi guys, where can I find this package now?
     
  24. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,269
  25. Qusdrok

    Qusdrok

    Joined:
    Jun 28, 2020
    Posts:
    19
    Last edited: Jan 14, 2021
  26. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,269
    Are those just custom arranged buttons? If so, you should be able to do that in the Unity UI without any problem.
     
  27. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    No, you can only manually arrange buttons this way.
     
  28. Qusdrok

    Qusdrok

    Joined:
    Jun 28, 2020
    Posts:
    19
    thank you so much guys
     
  29. Slashbot64

    Slashbot64

    Joined:
    Jun 15, 2020
    Posts:
    15
    Assets\New UI Widgets\Scripts\Spinner\SpinnerBase.cs(615,23): error CS0029: Cannot implicitly convert type 'UnityEngine.UI.InputField.SubmitEvent' to 'UnityEngine.UI.InputField.EndEditEvent'
     
  30. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    Are you using Unity 2021.1?

    Here is fix:
    Replace line in SpinnerBase.cs:
    Code (CSharp):
    1. InputField.SubmitEvent m_OnEndEdit = new InputField.SubmitEvent();
    with new lines:
    Code (CSharp):
    1. #if UNITY_2021_1_OR_NEWER
    2.         InputField.EndEditEvent m_OnEndEdit = new InputField.EndEditEvent();
    3. #else
    4.         InputField.SubmitEvent m_OnEndEdit = new InputField.SubmitEvent();
    5. #endif
    6.  
    In case if you using some other version, then you need to replace "UNITY_2021_1_OR_NEWER" with your Unity version.

    Unity has very bad release practices recently.
    Unity.UI package versions have the same number "1.0.0" in Unity 2020.1, Unity 2020.2, Unity 2021.1 releases, but in reality, they are not compatible (otherwise you did not get this error).
    In addition to it, the documentation is not actual.
     
    Last edited: Jan 15, 2021
    hopeful likes this.
  31. Slashbot64

    Slashbot64

    Joined:
    Jun 15, 2020
    Posts:
    15
    Thanks, yeah was trying 2021.

    "Unity has very bad release practices" ..dunno about the recently part.. they've had bad practices for years now.
     
    hopeful and ilih like this.
  32. Slashbot64

    Slashbot64

    Joined:
    Jun 15, 2020
    Posts:
    15
    is also the new ui widgets option screen is blank with this error in 2021
    Code (CSharp):
    1. ReflectionTypeLoadException: Exception of type 'System.Reflection.ReflectionTypeLoadException' was thrown.
    2. System.Reflection.Assembly.GetTypes () (at <9577ac7a62ef43179789031239ba8798>:0)
    3. UIWidgets.Utilities.GetType (System.String typename) (at Assets/New UI Widgets/Scripts/Utilities/Utilities.cs:65)
    4. UIWidgets.ThirdPartySupportMenuOptions.get_DataBindInstalled () (at Assets/New UI Widgets/Editor/ThirdPartySupportMenuOptions.cs:51)
    5. UIWidgets.ProjectSettings.get_DataBindStatus () (at Assets/New UI Widgets/Editor/ProjectSettings.cs:89)
    6. UIWidgets.ProjectSettings.DataBindBlock () (at Assets/New UI Widgets/Editor/ProjectSettings.cs:107)
    7. UIWidgets.ProjectSettings+<>c.<CreateSettingsProvider>b__8_0 (System.String searchContext) (at Assets/New UI Widgets/Editor/ProjectSettings.cs:147)
    8. UnityEditor.SettingsProvider.OnGUI (System.String searchContext) (at <506e8f90527a4ca99baf3418ceee7a30>:0)
    9. UnityEditor.SettingsWindow.DrawControls () (at <506e8f90527a4ca99baf3418ceee7a30>:0)
    10. UnityEditor.SettingsWindow.DrawSettingsPanel () (at <506e8f90527a4ca99baf3418ceee7a30>:0)
    11. UnityEngine.UIElements.IMGUIContainer.DoOnGUI (UnityEngine.Event evt, UnityEngine.Matrix4x4 parentTransform, UnityEngine.Rect clippingRect, System.Boolean isComputingLayout, UnityEngine.Rect layoutSize, System.Action onGUIHandler, System.Boolean canAffectFocus) (at <b82edc26c1654793bdaefb66b6a2a38a>:0)
    12. UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)
    13.  
    14.  
     
  33. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    Cannot reproduce it, but this fix should work:
    Replace
    Utilities.GetType()
    method in New UI Widgets / Scripts / Utilities / Utilities.cs with:
    Code (CSharp):
    1.         public static Type GetType(string typename)
    2.         {
    3.             foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
    4.             {
    5.                 Type[] types;
    6.                 try
    7.                 {
    8.                     types = assembly.GetTypes();
    9.                 }
    10.                 catch (System.Reflection.ReflectionTypeLoadException e)
    11.                 {
    12.                     types = e.Types;
    13.                 }
    14.  
    15.                 foreach (var assembly_type in types)
    16.                 {
    17.                     if ((assembly_type != null) && (assembly_type.FullName == typename))
    18.                     {
    19.                         return assembly_type;
    20.                     }
    21.                 }
    22.             }
    23.  
    24.             return null;
    25.         }
     
  34. Slashbot64

    Slashbot64

    Joined:
    Jun 15, 2020
    Posts:
    15
    That works actually thanks
     
  35. wx3labs

    wx3labs

    Joined:
    Apr 5, 2014
    Posts:
    66
    I'm seeing pretty bad performance in the table ListView, like a half second to refresh a table of 50 items. From the profiler it looks like it's almost all in ListUtilities.UpdateLayoutsRecursive:

    ListView.png

    Disabling the call (not surprisingly) completely messes up the layout, but replacing the call with a single ForceRebuildLayoutImmediate seems to have the same effect in my case, e.g.:

    Code (CSharp):
    1.         /// <summary>
    2.         /// Updates the component layout.
    3.         /// </summary>
    4.         /// <param name="component">Component.</param>
    5.         protected virtual void UpdateComponentLayout(TComponent component)
    6.         {
    7.             LayoutRebuilder.ForceRebuildLayoutImmediate(component.GetComponent<RectTransform>());
    8.             // LayoutUtilities.UpdateLayoutsRecursive(component);
    9.         }
    Is the recursive call doing something else that ForceRebuildLayoutImmediate doesn't?
     
  36. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    Are you sure that
    UpdateComponentLayout()
    is the right method to change?
    Profiler shows
    ListViewTypeBase.CalculateComponentSize()
    .

    No,
    UpdateLayoutsRecursive()
    was used only because when code was written
    LayoutRebuilder.ForceRebuildLayoutImmediate()
    did not exist.

    Another way to improve performance is to disable
    ListView.PrecalculateItemSizes
    , in this case in calculations will be used DefaultItem size until the actual item will be displayed.
     
    Last edited: Jan 19, 2021
  37. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,246
    Hi @ilih,
    Can you please provide a circular slider?
    Thanks
     
  38. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    I'll think about it.
     
    jGate99 likes this.
  39. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,246
    Appreciate that :)
     
  40. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,246
    Hi @ilih
    Remember you made a dialog example where we could put custom content?
    Now similarly, if i want to show a custom content inside toast so toast will have title, cross button, and also content area where i set a child.
    Please advise
     
  41. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    Sorry, but what is toast in this context?
     
    jGate99 likes this.
  42. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,246
    Sorry, i meant Notify component
     
  43. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    I'll try to add this in the next update.
     
    jGate99 likes this.
  44. jlhacode

    jlhacode

    Joined:
    Feb 20, 2020
    Posts:
    13
    How do we disable individual ListView items?

    In my shop UI I want to set an individual item so that it's non-selectable if my player doesn't have enough money. I would like to lower the transparency of the widget as well (similar to Buttons with interactable set to false).
     
  45. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    You can use
    ListView.CanSelect
    , it's accepting the index of the item and returns true if the item can be selected; and false otherwise.
    The text color of the non-selectable item is
    DefaultColor * DisabledColor
    , for the background color it works a similar way.
    Something like this:
    Code (CSharp):
    1. public void Start()
    2. {
    3.     ListView.CanSelect = CanBuy;
    4. }
    5.  
    6. bool CanBuy(int index)
    7. {
    8.     var item = ListView.DataSource[index];
    9.     return item.Price <= Player.Money;
    10. }
     
  46. Gladyon

    Gladyon

    Joined:
    Sep 10, 2015
    Posts:
    290
    I am trying to add a 'Refresh' button to the FolderDialog.

    In order to do that I've inherited 'FolderDialog' and I've added a 'Refresh()' method which remember the expanded nodes and the selected node.

    Then I call 'DirectoryTreeView.Nodes.BeginUpdate()' (not sure if it's useful).
    After that I call 'DirectoryTreeView.Clear()' and 'DirectoryTreeView.Init()' (I have modified the 'Clear()' method to reset 'isInited' to false so that 'Init()' will work).

    Then I restore the expanded nodes and the selection, and finally I call 'DirectoryTreeView.Nodes.EndUpdate()'.

    It all works fine except that there's no icon next to the directories which have sub-directories but aren't expanded (except for the root ones).
    In fact, I'm pretty sure that calling 'DirectoryTreeView.SelectDirectory()' has the same problem, some icons are missing.


    In order to expand the nodes, I use '.IsExpanded = true', exactly as it is done in 'DirectoryTreeView.SelectDirectory()'.
    I guess that the problem lies here, there's probably some call missing on each child of the newly expanded node in order to update its icon.
    I have looked for it a bit but I have no idea what must be done at that point.
     
  47. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    What exactly "Refresh" button should do?
    If you want to refresh all data then you can use
    DirectoryTreeView.RootDirectory = DirectoryTreeView.RootDirectory;

    after it, you need to restore expanded and selected nodes using
    GetNodeByPath()
    .

    If you want to refresh only the content of the specific directory then you can use
    node.Nodes = DirectoryTreeView.GetDirectoriesNodes(node.Item.FullName);


    Sub-directories loaded only when the parent directory is expanded on a toggle click to avoid long initialization.
    But sub-directories not automatically loaded when the node expanded from the code.
    So you need to add code to load sub-directories:
    Code (CSharp):
    1. node.IsExpanded = true;
    2. if (node.Nodes == null)
    3. {
    4.    node.Nodes = DirectoryTreeView.LoadNode(node);
    5. }
    6. node.Nodes.BeginUpdate();
    7. DirectoryTreeView.LoadNodes(node.Nodes);
    8. node.Nodes.EndUpdate();
     
    Last edited: Feb 5, 2021
  48. Gladyon

    Gladyon

    Joined:
    Sep 10, 2015
    Posts:
    290
    I need it to be able to reflect potential changes from other softwares, or to reflect the changes when I create/delete a directory.

    I just tried that but it crashed due to a collection being modified in a foreach.
    It may be because I have an old version of New UI Widgets.
    Anyway refreshing by clearing and re-initializing actually works quite well so it's OK for me.

    Excellent!
    It is exactly what I was missing.
    I just implemented it and it works perfectly.

    Thank you for your help, I'm amazed by the speed at which you answer questions, you're really doing a very good job!
     
  49. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    893
    I'll check it later, it should not happen.
     
  50. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,246
    Hi @ilih,

    Can you please provide a HexLayout?
    So we could make games like these.

    Thanks

     
unityunity