Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. Unity 2020 LTS & Unity 2021.1 have been released.
    Dismiss Notice
  3. 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. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,264
    I'll share the stack again when this happens as it happens randomly,
    reason im convinced this is not the datasource currently set is because when i comment the line old data source still remain there (Main Menu)

    but let me have proper stack when this happens for you to investigate,
    sorry for all this as i'm the maybe only user reusing same listview across multiple data sources , one idea however im thinking now is to keep 1 data source and then reset items from it.
     
  2. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    1. You can check Editor.log and Editor-prev.log for the stack trace, it should be there if the error happened in current or previous Unity Editor run.
    2. Is TurnBasedMatches a static variable?
    Since 2019.3 code is not always reloaded on entering play mode so static variables are not reset to default values, and this can cause bugs in editor mode.
    Way to reproduce:
    • enter play mode
    • select item for matches
    • wait until TurnBasedMatches assigned to ListView (here added callback to update ListView)
    • exit play mode
    • enter play mode again without any code changes
    • select item for matches
    • error happened (TurnBasedMatches still have the callback to update ListView from previous play mode and this cause error)
    You should add similar code to reset static variables to solve the problem:
    Code (CSharp):
    1.         [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
    2.         protected static void StaticInit()
    3.         {
    4.             TurnBasedMatches = new ObservableList<WSMultiItem>();
    5.         }
     
    Last edited: May 11, 2020
  3. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,264
    Hi ilih,
    Looks like i found one culprit after reading your advise. i'm using Unity's experimental playmode. I just disabled it and hopefuly this error goes away

    Thanks man, i'd never had personally thought about it.
     
  4. jGate99

    jGate99

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

    I'm using EasyLayout to show a 2 fixed rows layout where item appear in following order (top to bottom)

    [First Item][Third Item][Fifth Item]
    [Second ITem][Fourth Item]

    which works with this setting however there is unncessary gap between item unlike a proper flow layout.
    Capture.PNG

    Please advise
     
  5. vutruc80

    vutruc80

    Joined:
    Jun 28, 2013
    Posts:
    57

    Hi @ilih,
    For my Custom Tile View, i intercept the onPointerDown event to launch my custom action.
    Code (CSharp):
    1. ForEachComponent(slot => { slot.onPointerDown.RemoveListener(OnSubmit); slot.onPointerDown.AddListener(OnSubmit);});
    As you can see in the video, the behavior is:
    - Left click on an unselected item, it will become selected
    - Left click on a selected item then my custom action will be launched
    - This behavior is very fine but if i right click on an unselected item (later part of the video), it seems that the selected item will not be changed. Then if i left click on the old selected item, the custom action will not be launched until the second left click. It seems that the first left click only reselects the item. Which is odd.
    Can you explain to me this behavior and how to fix it?
    Thank you in advance.
     
  6. Petskus

    Petskus

    Joined:
    Jan 29, 2019
    Posts:
    23
    How is get current pull distance from ScrollRectEvents ?
     
  7. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    Please try Main Axis = Horizontal and LayoutType = Staggered.
    With Staggered layout, the main axis works the opposite way and it is not very intuitive.
     
    jGate99 likes this.
  8. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    Are you have some internal checks in OnSubmit function?
    Because onPointerDown event is called with every pointer down for all clicks: left, right, middle, etc.

    I think better is use onClickItem event, this will reduce checks to minimal.
    Code (CSharp):
    1.             ListView.ForEachComponent(slot =>
    2.             {
    3.                 slot.onClickItem.RemoveListener(OnSubmit);
    4.                 slot.onClickItem.AddListener(OnSubmit);
    5.             });
    6.         }
    7.  
    8.         protected int SelectedIndex = -1;
    9.  
    10.         private void OnSubmit(ListViewItem item)
    11.         {
    12.             if (ListView.IsSelected(item.Index))
    13.             {
    14.                 // if indices match then it's click on selected item
    15.                 if (SelectedIndex == item.Index)
    16.                 {
    17.                     Debug.Log("run custom action");
    18.                 }
    19.                 // otherwise save index
    20.                 else
    21.                 {
    22.                     SelectedIndex = item.Index;
    23.                 }
    24.             }
    25.         }

    ForEachComponent function is not very good to add listeners, because it works only with current instances.
    If ListView resized and more items became visible so newly created instances will not have listeners.

    Overriding AddCallback and RemoveCallback should work without a problem.
    Code (CSharp):
    1.         protected override void AddCallback(ListViewItem item)
    2.         {
    3.             base.AddCallback(item);
    4.  
    5.             item.onClickItem.AddListener(OnSubmit);
    6.         }
    7.  
    8.         protected override void RemoveCallback(ListViewItem item)
    9.         {
    10.             base.RemoveCallback(item);
    11.  
    12.             item.onClickItem.RemoveListener(OnSubmit);
    13.         }
     
    Last edited: May 14, 2020
  9. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    It can be calculated manually using ScrollRect.content.anchoredPosition.

    Or you can add following code to ScrollRectEvents.cs to use PullDistance property.
    Code (CSharp):
    1.         public float PullDistance
    2.         {
    3.             get;
    4.             protected set;
    5.         }
    And replace
    if
    's in OnDrag method:
    Code (CSharp):
    1.             if (ScrollRect.content.anchoredPosition.y < 0f)
    2.             {
    3.                 PullDistance = -ScrollRect.content.anchoredPosition.y;
    4.                 valid_distance = PullDistance >= Thresholds.Up;
    5.                 pullDirection = PullDirection.Up;
    6.             }
    7.             else if (ScrollRect.content.anchoredPosition.y > max_y)
    8.             {
    9.                 PullDistance = ScrollRect.content.anchoredPosition.y - max_y;
    10.                 valid_distance = PullDistance >= Thresholds.Down;
    11.                 pullDirection = PullDirection.Down;
    12.             }
    13.             else if (ScrollRect.content.anchoredPosition.x < 0f)
    14.             {
    15.                 PullDistance = -ScrollRect.content.anchoredPosition.x;
    16.                 valid_distance = PullDistance >= Thresholds.Left;
    17.                 pullDirection = PullDirection.Left;
    18.             }
    19.             else if (ScrollRect.content.anchoredPosition.x > max_x)
    20.             {
    21.                 PullDistance = ScrollRect.content.anchoredPosition.x - max_x;
    22.                 valid_distance = PullDistance >= Thresholds.Right;
    23.                 pullDirection = PullDirection.Right;
    24.             }
    25.             else
    26.             {
    27.                 PullDistance = 0f;
    28.             }
     
  10. vutruc80

    vutruc80

    Joined:
    Jun 28, 2013
    Posts:
    57
    - Yes i check if this is a left click or right click, different actions for different types of click. The issue is i doesn't understand why it works that way. Even with onPointerDown event, the current behavior is action is only triggered when we click on already selected item, otherwise the event is consumed elsewhere by an internal handler (i don't know where) and the new item will "auto" become "selected"
    - I will retry the onClickItem event and report the behavior.
    - Thanks for the AddCallback solution!
    - What's the semantic difference in meaning between IsSelected and SelectedIndex. I'm confused with the code: if (IsSelected(item.Index)) then SelectedIndex = item.Index; ???
     
    Last edited: May 15, 2020
  11. vutruc80

    vutruc80

    Joined:
    Jun 28, 2013
    Posts:
    57
    If we use onClickItem then it works fine because it is triggered only with Left Click then again i can't invoke custom action with Right Click. Maybe i will have to find a way to combine both events.
    EDIT 1: I think i have found the bug

    If we right click outside of selected item, at the Event System level there is no UI element selected but UIWidgets still keeps the selected item.
    What's the most elegant way to fix this bug?

    EDIT 1: my current solution:
    Code (CSharp):
    1.         protected override void Update()
    2.         {
    3.             if (SelectedIndex != -1 && EventSystem.current.currentSelectedGameObject == null)
    4.                 Deselect(SelectedIndex);
    5.         }
     
    Last edited: May 15, 2020
  12. Petskus

    Petskus

    Joined:
    Jan 29, 2019
    Posts:
    23
    Maybe it will be better add events OnPulling(direction, distanceNormal) and OnPullingStop() ?
     
  13. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    ListView has a MultipleSelect option, so ListView can have more than one selected item.
    SelectedIndex: index of the last selected item
    SelectedIndices: indices of all selected items, it returns a new List<int>, so
    ListView.SelectedIndices.Contains(index)
    is not optimal solution to check if index is selected.
    IsSelected(index): check is index is selected and no memory allocation unlike
    SelectedIndices.Contains(...)
    .
    If MultipleSelect is disabled then no difference between
    SelectedIndex==index
    and
    IsSelected(index)
    .

    It's not a bug.
    - EventSystem.current.currentSelectedGameObject is currently focused gameobject, which can be only one.
    - ListView selected items are just selected items, not necessarily currently focused gameobject.
    - ListView should not deselect items on click outside ListView.
    If selected items are deselected on click outside ListView then the selection is useless, you can not have a button (or anything else) working with selected items, because when you click items no more selected.

    If you need to deselect items on click outside ListView then you can do it this way:
    Code (CSharp):
    1.         Camera CurrentCamera;
    2.  
    3.         void Update()
    4.         {
    5.             var is_click = Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1) || Input.GetMouseButtonDown(2);
    6.             if (is_click)
    7.             {
    8.                 Vector2 point;
    9.                 // if mouse position is outside ListView
    10.                 if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(ListView.transform as RectTransform, Input.mousePosition, CurrentCamera, out point))
    11.                 {
    12.                     ListView.Deselect(ListView.SelectedIndex);
    13.                 }
    14.             }
    15.         }
     
  14. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    Not sure, I think
    UnityEvent<ScrollRectEvents, PullDirection>
    will be better if you need to distance then probably you also need Thresholds values and maybe some other values too.
    I do not think OnPullingStop is required, already have OnPull (on success), and OnPullCancel (on cancel) events.

    Code (CSharp):
    1.  
    2.         [Serializable]
    3.         public class PullingEvent : UnityEvent<ScrollRectEvents, PullDirection>
    4.         {
    5.         }
    6.  
    7.         [SerializeField]
    8.         public PullingEvent OnPulling = new PullingEvent();
    9.  
    10.         public virtual void OnDrag(PointerEventData eventData)
    11.         {
    12.             ....
    13.  
    14.             OnPulling.Invoke(this, pullDirection);
    15.  
    16.             if (valid_distance)
    17.             ....
    18.         }
     
  15. tim44

    tim44

    Joined:
    May 15, 2019
    Posts:
    56
    I may be missing something obvious, but is there a way to reformat all items in a list? This code is working, but thought there might be an easy way without recreating the list:
    Code (CSharp):
    1. public void refreshListView(List<ListViewItemDescription> mList, GameObject listView)
    2.     {
    3.  
    4.         var obj = listView.GetComponent<ListView>();
    5.         obj.DataSource.Clear();
    6.         obj.DataSource.AddRange(mList);
    7.  
    8.     }
     
  16. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    Fastest way is to use
    ListView.Resize()
    method or change
    ListViewCustom.UpdateView()
    from
    protected
    to
    public
    and use it (this method will be changed to
    public
    in next release).

    Right way is add INotifyPropertyChanged implementation to ListViewItemDescription class.
    Public fields should be converted to property and raise
    PropertyChanged()
    event when any property changed.
    This way ListView will be automatically updated if any property changed.

    Old code:
    Code (CSharp):
    1.     [Serializable]
    2.     public class ListViewItemDescription
    3.     {
    4.         public string Name;
    5.     }
    New code:
    Code (CSharp):
    1.     [Serializable]
    2.     public class ListViewItemDescription : INotifyPropertyChanged
    3.     {
    4.         [SerializeField] // required because field is not public anymore
    5.         [FormerlySerializedAs("Name")] // required to avoid serialized data loss with the field name changed
    6.         private string name;
    7.  
    8.         public string Name // replace field with public property with same name
    9.         {
    10.             get => name;
    11.  
    12.             set
    13.             {
    14.                 if (name != value)
    15.                 {
    16.                     name = value;
    17.                     Changed();
    18.                 }
    19.             }
    20.         }
    21.  
    22.         protected void Changed([CallerMemberName] string propertyName = "")
    23.         {
    24.             PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    25.         }
    26.  
    27.         public event PropertyChangedEventHandler PropertyChanged = Utilities.DefaultPropertyHandler;
    28.     }
     
    Last edited: May 15, 2020
    tim44 likes this.
  17. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,264
    Hi @ilih,
    Is there an even for datasource change of ListView?
    an event which triggers whenever i call ListView.DataSource = DS;
     
  18. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    OnUpdateView(), but this event also happens on a ListView scroll and any DataSource changes.
     
    jGate99 likes this.
  19. vutruc80

    vutruc80

    Joined:
    Jun 28, 2013
    Posts:
    57


    Hi @ilih , further testing your solution, i'm observing this issue. A page normally has 3 x 4 = 12 items, as you can see in the load grid (having 24 items) everything seems fine. But in save grid (having 25 items) somehow the tileview only shows 3 blocks. Do you have any suggestion of where this issue probably comes from. Thank you very much for the great support :)
     
  20. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    Are TileViews settings identical?
    If yes, then something was wrong with a calculation of how many items are visible.
    Probably ScrollRect size was changed, or DefaultItem size was changed since the initial calculation.
    Please try to use
    ListView.Resize()
    or
    ListView.ChangeDefaultItemSize(new Vector(...))
    after click on load when ListView gameobject already active.
     
  21. vutruc80

    vutruc80

    Joined:
    Jun 28, 2013
    Posts:
    57
    Yes they are identical. And no calling ListView.Resize() doesn't solve the issue. I made a wild guess that there is something to do with the execution order so i converted UpdateMargin into a Coroutine
    Code (CSharp):
    1.        void UpdateMarginNextFrame()
    2.         {
    3.             StartCoroutine(UpdateMargin());
    4.         }
    then it works now.
    But after i makes a change in DataSource (adding a new item) then the issues reappears and i notice that UpdateMargin isn't invoked so i try to add:
    Code (CSharp):
    1. ListView.DataSource.OnChange += UpdateMarginNextFrame;
    but it doesn't work.
    Any idea?

    EDIT 1: This is the ItemsPewRow calculation code in the method CalculateMaxVisibleItems() of class TileViewTypeFixed:
    Code (CSharp):
    1.                 var width = Owner.ScrollRectSize.x + spacing_x - Owner.LayoutBridge.GetFullMarginX();
    2.                 var height = Owner.ScrollRectSize.y + spacing_y - Owner.LayoutBridge.GetFullMarginY();
    3.  
    4.                 if (Owner.IsHorizontal())
    5.                 {
    6.                     ItemsPerRow = Mathf.CeilToInt(width / (Owner.ItemSize.x + spacing_x)) + 1;
    7.                     ItemsPerRow = Mathf.Max(MinVisibleItems, ItemsPerRow);
    8.  
    9.                     ItemsPerColumn = Mathf.FloorToInt(height / (Owner.ItemSize.y + spacing_y));
    10.                     ItemsPerColumn = Mathf.Max(1, ItemsPerColumn);
    11.                     ItemsPerColumn = Owner.LayoutBridge.RowsConstraint(ItemsPerColumn);
    12.                 }
    So if we increase the margin(GetFullMarginX()), the width will be decreased and ItemsPerRow will be also decreased. It seems that we must restore the original margin value before the execution of this method

    EDIT 2: I make it works now, with your old PaginatorFix code plus a dirty hack in class TileViewTypeFixed
    Code (CSharp):
    1.                 //var width = Owner.ScrollRectSize.x + spacing_x - Owner.LayoutBridge.GetFullMarginX();
    2.                 var width = Owner.ScrollRectSize.x + spacing_x;
    But it will be a painful job of maintenance if i ever want to update the UI Widgets library. Any suggestion for a more elegant solution?

    EDIT 3: We still have to wrap UpdateMargin in a CoRoutine and execute it several frames later so that every info has been correctly updated before its execution
     
    Last edited: May 18, 2020
  22. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    Thanks, I understood the problem and working on a solution.
     
  23. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    Fixed in v1.12.2b1
     
    vutruc80 likes this.
  24. cgrow67

    cgrow67

    Joined:
    May 31, 2016
    Posts:
    20
    Would it be possible to get double click support / events for the ListView and TileView ?? I've rigged some stuff from the outside but its almost impossible as changing selections loses a mouse click.
     
  25. cgrow67

    cgrow67

    Joined:
    May 31, 2016
    Posts:
    20
    I updated to 1.12.1 today. There seems to be an error in the asmdef as there was no reference to TMPro. It was enabled in my project before update New UI Widgets. I guess it didn't think TextMeshPro was enabled.. Not sure.. so I updated the asmdef files and now it all compiles.

    When I drop a widgets onto my scene they show up all white as though the theme or some assets are missing. I've also tried applying theme and this doesn't work either.

    I'm using Unity3d 2019.3.13f1. I've also installed New UI Widgets 1.12.2b1 for Unity 2019.3.0f6 and still the same result.

    Okay.. that was some stress.. but finally muddled my way though it .. Seems going to build settings and changing the platform to another platform finally got the missing assets setup. My application once again looks good and new widgets look correct as well. Do you think I should continue with the 1.12.2b1 ?
     
    Last edited: May 19, 2020
  26. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    You can use DefaultItem.onDoubleClick event.
    Like this:
    Code (CSharp):
    1.     public class YourListView : ListViewCustom<YourListViewItemComponent, YourListViewItem>
    2.     {
    3.         protected override void AddCallback(ListViewItem item)
    4.         {
    5.             base.AddCallback(item);
    6.             item.onDoubleClick.AddListener(ProcessDoubleClick);
    7.         }
    8.  
    9.         protected override void RemoveCallback(ListViewItem item)
    10.         {
    11.             base.RemoveCallback(item);
    12.             item.onDoubleClick.RemoveListener(ProcessDoubleClick);
    13.         }
    14.  
    15.         void ProcessDoubleClick(int index)
    16.         {
    17.             Debug.Log("double click: " + DataSource[index]);
    18.         }
    19.  
    or this:
    Code (CSharp):
    1.     public class YourListViewItemComponent : ListViewItem, IViewData<YourListViewItem>
    2.     {
    3.         protected override void Start()
    4.         {
    5.             base.Start();
    6.  
    7.             onDoubleClick.AddListener(ProcessDoubleClick);
    8.         }
    9.  
    10.         void ProcessDoubleClick(int index)
    11.         {
    12.             Debug.Log("double click: " + (Owner as YourListView).DataSource[index]);
    13.         }
    Package has code that should restore TMPro reference after the update, but either previous version was old, and without such code or the code does not work for some reason, I'll check it.
    Disable TMPro support and enabling it back solves the problem.

    It can happen because of the empty style used as default and it automatically applied to newly created widgets.
    Please open "New UI Widgets/Styles/UIWidgets Style Default," check it values (it should not be all white color or null), and set it as default.
    If UIWidgets Style Default values are all white color or null, then try to import package again, sometimes import works incorrectly.

    You can use "t:UIWidgets.Styles.Style" to find all styles and check which one is used by default.
     
    Last edited: May 19, 2020
    cgrow67 likes this.
  27. cgrow67

    cgrow67

    Joined:
    May 31, 2016
    Posts:
    20
    Thank you so much. The double click handler works perfectly!

    Yes, I can see that Import if flawed. This is something they really need to fix.

    Got the style setup and back to my custom style.

    We really appreciate the quick response!
     
    ilih likes this.
  28. Petskus

    Petskus

    Joined:
    Jan 29, 2019
    Posts:
    23
    An error was founded in the Spinner with Min=2, Max=10.
    The value will never become 10 because the Spinner.ValidateFull () checks the new value char by char.
    The first "1"is not inbound and the result is reset.
     
  29. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    You can change validation from "On Key Down" to "On End Input", in this case, validation will be done when Spinner.InputField loses focus
     
    Petskus likes this.
  30. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,264
    Hi @ilih
    if modal is true, then i also want to hide close icon (top right) in dialogs.
    Please advise
    Thanks
     
  31. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    You can either use a different template for the modal Dialog without a close button or use wrapper function for the Show() to show/hide the close button on condition.
    Code (CSharp):
    1.     DialogTemplate.Clone().ShowModal(....)
    2.  
    3.     public static class DialogExtensions
    4.     {
    5.         public static void ShowModal(this Dialog dialog,
    6.             string title = null,
    7.             string message = null,
    8.             IList<DialogButton> buttons = null,
    9.             string focusButton = null,
    10.             Vector3? position = null,
    11.             Sprite icon = null,
    12.             bool modal = false,
    13.             Sprite modalSprite = null,
    14.             Color? modalColor = null,
    15.             Canvas canvas = null,
    16.             RectTransform content = null,
    17.             Action onClose = null,
    18.             Func<int, bool> onCancel = null)
    19.         {
    20.             var button = dialog.transform.Find("Header/CloseButton");
    21.             if (button != null)
    22.             {
    23.                 button.gameObject.SetActive(!modal);
    24.             }
    25.  
    26.             dialog.Show(title, message, buttons, focusButton, position, icon, modal, modalSprite, modalColor, canvas, content, onClose, onCancel);
    27.         }
    28.     }
     
    jGate99 likes this.
  32. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,264
    Hi @ilih,
    I extend Dialog class to handle some custom cases, however there is one problem that Clone() method returns base class Dialog and not my extend class. I can cast it, but i want to avoid casting.
    Please advise
     
  33. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    I do not think it is possible to avoid type casting at all in these cases.
    You can limit the type casting to a single function like this:
    Code (CSharp):
    1.         public new DialogNew Clone()
    2.         {
    3.             return base.Clone() as DialogNew;
    4.         }
    Or you can try to use extensions methods instead of the derived class if it is possible.
     
    jGate99 likes this.
  34. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,264
    Hi @ilih
    When i pass the same array of buttons (DialogButton[] buttons)
    to a dialog, every time i show
    button orders keep changing in alert itself.
    For example if its "OK", and "Cancel"
    then one time "Cancel" appear in start, and then other time cancel appear in end and it keep happening.
     
  35. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    Sorry, fixed in v1.12.2b3
     
    jGate99 likes this.
  36. Arcanor

    Arcanor

    Joined:
    Nov 4, 2009
    Posts:
    277
    @ilih - I'm still so very impressed at how much effort you put in to support this package. Thank you so much! It makes me much more confident as a user to know that problems will be fixed. You rock!
     
    jGate99, hopeful and ilih like this.
  37. cgrow67

    cgrow67

    Joined:
    May 31, 2016
    Posts:
    20
    Is there any chance to get slightly better support for Selectable?
    I know the thing is a major PITA but it would help us.

    Switch for example doesn't seem to support color modification when its selected ( has focus ).

    I have some screen with list of numbers and then switches.. it would be nice to be able to keyboard navigate to them and change them. The navigation does work but the selected switch doesn't get color augmented. In a group of switches you don't know what is selected and will change.

    Thanks,

    Chris
     
  38. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    You need to change Switch.TargetGraphic to Mark or Background.
    If you want to control colors of both then you need to also add SelectableHelper component and set it TargetGraphic.
     
  39. mrnas

    mrnas

    Joined:
    Jan 13, 2018
    Posts:
    14
    Hi, i tried generating Widgets for my classes and there are Errors in the generated GraphicsForeground Methods:

    [...]\Scripts\ListViewComponentMultiObjectMesh.cs(56,43): error CS0103: The name 'Utilities' does not exist in the current context


    My classes:
    Code (CSharp):
    1.  [System.Serializable]
    2.     public class MultiObjectMesh
    3.     {
    4.         public MeshTopology topology;
    5.         public SubObject[] subObjects = new SubObject[0];
    6.  
    7.     }
    8.  
    9.     [System.Serializable]
    10.     public class SubObject
    11.     {
    12.         public Color color = Color.gray;
    13.  
    14.         public Vector3[] vertices = new Vector3[0];
    15.  
    16.         public int[] indices = new int[0];
    17.     }

    Generated Method:

    Code (CSharp):
    1. /// <summary>
    2.         /// Gets foreground graphics for coloring.
    3.         /// </summary>
    4.         public override UnityEngine.UI.Graphic[] GraphicsForeground
    5.         {
    6.             get
    7.             {
    8.                 return new UnityEngine.UI.Graphic[] { Utilities.GetGraphic(topology),  };
    9.             }
    10.         }
    How can i fix it?
     
  40. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    You need to replace
    Utilities.GetGraphic(topology)
    with
    UIWidgets.Utilities.GetGraphic(topology)


    Upd: released v1.12.2f1 with the fixed bug
     
    Last edited: Jun 6, 2020
  41. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,264
    Hi @ilih,
    I'm having trouble with tile view, it doesnt show all the items and tile view looks in 30% area, and when i scrollup items appear quickly, plz advise
     
  42. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    Can you show a screenshot or video of the tile view, and tile view settings?
     
    jGate99 likes this.
  43. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,264
    my bad, i was not choosing Tile View option from the List Type, now it works perfectly.
     
  44. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,264
    Hi @illih,
    How can we make a listview that always have a selected item, in short, user is unable to deselct an item, only thing user can do is select another item like radio buttons where one item is always selected.
    Thanks
     
  45. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    Disable ListView.MultipleSelect (only one item can be selected) and set SelectedIndex to 0 (select the first item by default).
     
    jGate99 likes this.
  46. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,264
    Hi @ilih
    I'm using 2020.1B13 and whenever i open my custom created combobox i get this error, any advise what im doing wrong?
    Thanks




    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. UIWidgets.ListViewBase.SelectComponentByIndex (System.Int32 index) (at Assets/New UI Widgets/Scripts/ListView/ListViewBase.cs:1045)
    3. UIWidgets.ListViewBase.SelectComponent () (at Assets/New UI Widgets/Scripts/ListView/ListViewBase.cs:1032)
    4. UIWidgets.ComboboxCustom`3[TListViewCustom,TComponent,TItem].ShowList () (at Assets/New UI Widgets/Scripts/Combobox/ComboboxCustom.cs:360)
    5. UIWidgets.ComboboxCustom`3[TListViewCustom,TComponent,TItem].ToggleList () (at Assets/New UI Widgets/Scripts/Combobox/ComboboxCustom.cs:326)
    6. UnityEngine.Events.InvokableCall.Invoke () (at <f558b8ea7f6c45ffb8d17cad3257580d>:0)
    7. UnityEngine.Events.UnityEvent.Invoke () (at <f558b8ea7f6c45ffb8d17cad3257580d>:0)
    8. UnityEngine.UI.Button.Press () (at D:/Program Files/Unity Hub Editors/2020.1.0b13/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/UI/Core/Button.cs:68)
    9. UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at D:/Program Files/Unity Hub Editors/2020.1.0b13/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/UI/Core/Button.cs:110)
    10. UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at D:/Program Files/Unity Hub Editors/2020.1.0b13/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/EventSystem/ExecuteEvents.cs:50)
    11. UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at D:/Program Files/Unity Hub Editors/2020.1.0b13/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/EventSystem/ExecuteEvents.cs:261)
    12. UnityEngine.EventSystems.EventSystem:Update() (at D:/Program Files/Unity Hub Editors/2020.1.0b13/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/EventSystem/EventSystem.cs:376)
    13.  
     
  47. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    On toggle, Combobox scrolls ListView to the last selected item and then select this item gameobject with EventSystem (this is needed to support keyboard or gamepad navigation).
    The error happens because the selected item is not visible despite scroll to it, so it does not have gameobject to select.
    Why this can happen:
    • ListView type is the variable size and PrecalculateItemSizes disabled -> scroll is imprecise -> item not visible
    • for some reason selected index is invalid (item with such index does not exist), so the item cannot be visible because not exists. (I think it's impossible to set an invalid selected index, but I maybe missed some checks.)

    Solution to prevent error:
    modify file ListViewBase.cs
    SelectComponentByIndex(int index)
    replace old line
    EventSystem.current.SetSelectedGameObject(GetComponent(index).gameObject);

    with
    Code (CSharp):
    1.             var component = GetComponent(index);
    2.             if (component != null)
    3.             {
    4.                 EventSystem.current.SetSelectedGameObject(component.gameObject);
    5.             }
    SelectComponentByIndex(AxisEventData eventData, int index)
    replace old line
    eventData.selectedObject = GetComponent(index).gameObject;

    with
    Code (CSharp):
    1.             var component = GetComponent(index);
    2.             if (component != null)
    3.             {
    4.                 eventData.selectedObject = component.gameObject;
    5.             }
     
    jGate99 likes this.
  48. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,264
    Hi @ilih,
    I have list view working perfectly, but what i want is reset drawn items, I called updateItems and Updateview
    But it looks like StateSelected , StateDefault etc dont get called.
    Please advise
     
  49. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    905
    I checked both UpdateItems() and UpdateView() methods and they both invokes StateDefault() and StateSelected(). (You need to call only UpdateView() to refresh item.)
    Please check StateDefault() and StateSelected() definitions: should be
    public override void
    ; otherwise those functions will be considered as completely separate functions and not be invoked.
     
    jGate99 likes this.
  50. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,264
    Thanks, My Mistake.

    ======


    Hi @ilih,

    One more question. I have a list view which is inside a canvas group. If i set canvas group interactable = false. But list view inside is still interactable.

    Update 2:
    Directly selecting interactable = false on listview , but listview is still interacatable.

    Please advise
     
unityunity