Author Topic: Reordering items in UIGrid or UITable by dragging  (Read 11261 times)

dmitry

  • Guest
Reordering items in UIGrid or UITable by dragging
« on: October 06, 2012, 04:34:26 AM »
I'm very very new to NGUI and need to create a list of items that could be reordered by dragging a handle on a side of the items.

I think I can make it draggable by the handle, and when I start dragging, the item should be removed from the list and then when I move it a placeholder should be inserted in the list to display where the item would go. But how can I insert something in the middle of the UIGrid or UITable?

Has anybody done this before?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Reordering items in UIGrid or UITable by dragging
« Reply #1 on: October 06, 2012, 09:27:28 AM »
If you don't call UIGrid's reposition function, you can safely remove and add items to it wherever you wish. The position only gets recalculated when you call that function. If you want a specific order, just set the "sorted" property to "true" and name entries sequentially, such as: "001", "002", etc.

broken

  • Full Member
  • ***
  • Thank You
  • -Given: 1
  • -Receive: 4
  • Posts: 140
    • View Profile
Re: Reordering items in UIGrid or UITable by dragging
« Reply #2 on: October 31, 2013, 08:52:31 AM »
UP!

I create chat where each message is a separate UILabel in UITable (Clipped Panel) (needed in order for me to hang up the collider to special areas of the text, eg. nickname).
I have a limit on the number of messages in chat (number of labels).

The maximum limit for example 30-50 messages.
Messages may contain emoticons, colors, colliders, and can be a few lines of text.
Сhat messages can come fast enough, so what is a better (effective and faster):
1. Rename all existing items, sorting by name and update item content (reuse items).
2. Removal of the first element and the creation of (adding) new item in the end.

Thanks!

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Reordering items in UIGrid or UITable by dragging
« Reply #3 on: November 01, 2013, 08:24:22 AM »
Test it and find out. I'd lean toward 1.

broken

  • Full Member
  • ***
  • Thank You
  • -Given: 1
  • -Receive: 4
  • Posts: 140
    • View Profile
Re: Reordering items in UIGrid or UITable by dragging
« Reply #4 on: November 02, 2013, 01:30:00 AM »
Test it and find out. I'd lean toward 1.

I tried a test (in Editor! with Stopwatch for 100 items and max limit 30), and the options to remove the first item, and adding new item faster.
Code for recreate item (without sorting), ElapsedMilliseconds ~145 :
  1.         public void AddMessage(ChatListMessageData message)
  2.         {
  3.                 List<Transform> items = itemsRoot.children;
  4.                
  5.                 if (items.Count == maxMessages)
  6.                 {
  7.                         NGUITools.Destroy(items[0].gameObject);
  8.                 }
  9.                
  10.                 GameObject item = NGUITools.AddChild(itemsRoot.gameObject, itemPrefab);
  11.                 ChatListMessageItem chatItem = item.GetComponent<ChatListMessageItem>();
  12.                 chatItem.message = message;
  13.                
  14.                 itemsRoot.Reposition();
  15.                
  16.                 RefreshScrollBar();
  17.         }
  18.  

Code for reuse item (with all items renaming and table sorting), ElapsedMilliseconds ~186 :
  1.         public void AddMessage(ChatListMessageData message)
  2.         {              
  3.                 GameObject item = null;
  4.                 List<Transform> items = itemsRoot.children;
  5.                 string itemName = "Item";
  6.                
  7.                 if (items.Count < maxMessages)
  8.                 {
  9.                         item = NGUITools.AddChild(itemsRoot.gameObject, itemPrefab);
  10.                         item.name = itemName + items.Count.ToString("000");
  11.                 }
  12.                 else
  13.                 {
  14.                         item = items[0].gameObject;
  15.                         for (int i = 1; i < items.Count; ++i)
  16.                         {
  17.                                 items[i].gameObject.name = itemName + (i - 1).ToString("000");
  18.                         }
  19.                         item.name = itemName + (items.Count - 1).ToString("000");
  20.                 }
  21.                
  22.                 ChatListMessageItem chatItem = item.GetComponent<ChatListMessageItem>();
  23.                 chatItem.message = message;
  24.                
  25.                 itemsRoot.Reposition();
  26.                
  27.                 RefreshScrollBar();
  28.         }
  29.  

Code for reuse item (with last item renaming and table sorting), ElapsedMilliseconds ~171:
  1.         public void AddMessage(ChatListMessageData message)
  2.         {              
  3.                 GameObject item = null;
  4.                 List<Transform> items = itemsRoot.children;
  5.                 string itemName = "Item";
  6.                
  7.                 if (items.Count < maxMessages)
  8.                 {
  9.                         item = NGUITools.AddChild(itemsRoot.gameObject, itemPrefab);
  10.                         item.name = itemName + items.Count.ToString("000");
  11.                 }
  12.                 else
  13.                 {
  14.                         item = items[0].gameObject;
  15.                         item.name = itemName + _lastIndex.ToString("000");
  16.                 }
  17.                
  18.                 ChatListMessageItem chatItem = item.GetComponent<ChatListMessageItem>();
  19.                 chatItem.message = message;
  20.                 _lastIndex++;
  21.                
  22.                 itemsRoot.Reposition();
  23.                
  24.                 RefreshScrollBar();
  25.         }
  26.  

If the first option (for a new item creation ) also include sorting, then time almost equally (~178)
Maybe I'm doing something wrong to be reused?
« Last Edit: November 04, 2013, 03:09:05 AM by broken »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Reordering items in UIGrid or UITable by dragging
« Reply #5 on: November 02, 2013, 08:03:24 AM »
Creation means GC allocation, meaning spikes in performance that are best avoided.

broken

  • Full Member
  • ***
  • Thank You
  • -Given: 1
  • -Receive: 4
  • Posts: 140
    • View Profile
Re: Reordering items in UIGrid or UITable by dragging
« Reply #6 on: November 03, 2013, 07:02:42 AM »
Well, then try to use the renaming of all the elements and sorting. Thanks! :)

broken

  • Full Member
  • ***
  • Thank You
  • -Given: 1
  • -Receive: 4
  • Posts: 140
    • View Profile
Re: Reordering items in UIGrid or UITable by dragging
« Reply #7 on: November 04, 2013, 12:12:00 AM »
Decided to look into the profiler, that's what it shows (attach).
Here I am adding 100 items (in for loop test) with a limit of 30 items. If beyond the limit, all the elements are renamed and sorted in the above code.
As in your opinion, is this normal?
« Last Edit: November 04, 2013, 12:24:01 AM by broken »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Reordering items in UIGrid or UITable by dragging
« Reply #8 on: November 04, 2013, 12:20:52 PM »
Drop a kinematic rigidbody on your UIRoot.

broken

  • Full Member
  • ***
  • Thank You
  • -Given: 1
  • -Receive: 4
  • Posts: 140
    • View Profile
Re: Reordering items in UIGrid or UITable by dragging
« Reply #9 on: November 04, 2013, 01:22:56 PM »
Drop a kinematic rigidbody on your UIRoot.

It is normal to have to throw kinematic Rigidbody on UIRoot? Not seen this in your examples. Why is that? Is because of the sorting of elements and their colliders? Why no one else was interested about it on this forum :)

UPD1: Yes, I added Rigidbody, operations with static collider disappeared from the profiler, now the Dynamic Collider, but now there is not much colliders calls.
What are the disadvantages to expect from the addition of Rigidbody on UIRoot?

And yet, limit on the number of messages is known in advance, I think it might be worth in advance in the editor to create dummy elements of the chat list (pool), and make them inactive (+ Table - Hide Inactive). And as a new message in the chat, instead of the original creation, to make them active?
« Last Edit: November 05, 2013, 12:10:04 AM by broken »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Reordering items in UIGrid or UITable by dragging
« Reply #10 on: November 05, 2013, 05:33:49 AM »
Rigidbody trick supposedly helps due to how Unity works. It's generally good to have rigidbodies on panels, but UIRoot works as well. In the tests I've done, it always usually decreased performance rather than increase it (albeit slightly), so it's more for physics-intensive scenes. I guess none of mine fell under that category.

Anyway, we're deviating from the original topic. As I mentioned, lean towards what makes more sense / performs better in your case and don't worry about it.