Author Topic: Bug in Scroll bar with Scroll view  (Read 5393 times)

Aleksandr

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Bug in Scroll bar with Scroll view
« on: March 24, 2014, 05:32:26 AM »
When ScrollView.showCondition == Always
If a element amount less than the maximum amount of elements in the visible container.
Then scroll bar foreground calculated not correctly. Is size < 1.
Further reducing the number of elements leads to a reduction in size, although it should be equal to 1.
It can easily be played on a standard Example 11 - Drag & Drop.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Bug in Scroll bar with Scroll view
« Reply #1 on: March 24, 2014, 04:59:20 PM »
Change UIScrollView.UpdateScrollbars function on line 478 of UIScrollView to this:
  1.         protected void UpdateScrollbars (UIProgressBar slider, float contentMin, float contentMax, float contentSize, float viewSize, bool inverted)
  2.         {
  3.                 if (slider == null) return;
  4.  
  5.                 mIgnoreCallbacks = true;
  6.                 {
  7.                         if (viewSize < contentSize)
  8.                         {
  9.                                 contentMin = Mathf.Clamp01(contentMin / contentSize);
  10.                                 contentMax = Mathf.Clamp01(contentMax / contentSize);
  11.  
  12.                                 float contentPadding = contentMin + contentMax;
  13.                                 slider.value = inverted ? ((contentPadding > 0.001f) ? 1f - contentMin / contentPadding : 0f) :
  14.                                         ((contentPadding > 0.001f) ? contentMin / contentPadding : 1f);
  15.  
  16.                                 UIScrollBar sb = slider as UIScrollBar;
  17.                                 if (sb != null) sb.barSize = 1f - contentPadding;
  18.                         }
  19.                         else
  20.                         {
  21.                                 contentMin = Mathf.Clamp01(-contentMin / contentSize);
  22.                                 contentMax = Mathf.Clamp01(-contentMax / contentSize);
  23.  
  24.                                 float contentPadding = contentMin + contentMax;
  25.                                 slider.value = inverted ? ((contentPadding > 0.001f) ? 1f - contentMin / contentPadding : 0f) :
  26.                                         ((contentPadding > 0.001f) ? contentMin / contentPadding : 1f);
  27.  
  28.                                 if (contentSize > 0)
  29.                                 {
  30.                                         contentMin = Mathf.Clamp01(contentMin / contentSize);
  31.                                         contentMax = Mathf.Clamp01(contentMax / contentSize);
  32.                                         contentPadding = contentMin + contentMax;
  33.                                 }
  34.  
  35.                                 UIScrollBar sb = slider as UIScrollBar;
  36.                                 if (sb != null) sb.barSize = 1f - contentPadding;
  37.                         }
  38.                 }
  39.                 mIgnoreCallbacks = false;
  40.         }
« Last Edit: March 24, 2014, 05:13:20 PM by ArenMook »

Aleksandr

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: Bug in Scroll bar with Scroll view
« Reply #2 on: March 25, 2014, 02:38:42 AM »
Thanks.
I found incorrect behavior if viewSize >= contentSize. (Test by Example 11)
If elements in left column < 4 then scrollbar.size = 0.995025.
Which makes it possible to move items. As version i fix that as:

 protected void UpdateScrollbars (UIProgressBar slider, float contentMin, float contentMax, float contentSize, float viewSize, bool inverted)
    {
        if (slider == null) return;

        mIgnoreCallbacks = true;
        {
            if (viewSize < contentSize)
            {
                contentMin = Mathf.Clamp01(contentMin / contentSize);
                contentMax = Mathf.Clamp01(contentMax / contentSize);

                float contentPadding = contentMin + contentMax;
                slider.value = inverted ? ((contentPadding > 0.001f) ? 1f - contentMin / contentPadding : 0f) :
                    ((contentPadding > 0.001f) ? contentMin / contentPadding : 1f);

                UIScrollBar sb = slider as UIScrollBar;
                if (sb != null) sb.barSize = 1f - contentPadding;
            }
            else
            {
                contentMin = Mathf.Clamp01(-contentMin / contentSize);
                contentMax = Mathf.Clamp01(-contentMax / contentSize);

                float contentPadding = contentMin + contentMax;
                slider.value = inverted ? ((contentPadding > 0.001f) ? 1f - contentMin / contentPadding : 0f) :
                    ((contentPadding > 0.001f) ? contentMin / contentPadding : 1f);

                if (contentSize > 0)
                {
                    contentMin = Mathf.Clamp01(contentMin / contentSize);
                    contentMax = Mathf.Clamp01(contentMax / contentSize);
                    contentPadding = contentMin + contentMax;
                }

                UIScrollBar sb = slider as UIScrollBar;
                if (sb != null)
                {
                    contentPadding = (contentPadding < 0.01f) ? 0 : 1;
                    sb.barSize = 1f - contentPadding;
                }

            }
        }
        mIgnoreCallbacks = false;
    }

Samuraisa

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 15
    • View Profile
Re: Bug in Scroll bar with Scroll view
« Reply #3 on: March 25, 2014, 07:38:54 AM »
Hi! Sorry for posting here, do not want to create separate topic for this.
I've some bug with Scroll View and Scroll Bar. I'm using "fixed size" ui scheme and creating an inventory list with UIScrollView with vertical UIScrollBar and OnlyIfNeeded show condition.
As workaround for auto-centering of content in UIScrollView when content is not enough to overflow scroll view size, I make the content-list-container UIWidget.height equal to UIScrollView.height, but sometimes scroll bar becomes visible. That is becouse NGUI used comparison of float values in shouldMoveVertically (and in shouldMoveHorizontally too), not integer what the pixel values are.

This is the fix for me:
return Mathf.RoundToInt(size) > Mathf.RoundToInt(mPanel.height); // this is for shouldMoveVertically

But I want to ask will it be applied to the official NGUI code or I'll need to apply it for myself every ver. of NGUI?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Bug in Scroll bar with Scroll view
« Reply #4 on: March 26, 2014, 02:25:23 AM »
@Aleksandr: No, that code won't work. If the content doesn't fit into the view, then your code will cause the bar's size to be 0. Try it in the drag & drop example. This code would be better:
  1.                         UIScrollBar sb = slider as UIScrollBar;
  2.  
  3.                         if (sb != null)
  4.                         {
  5.                                 if (contentPadding < 0.001f) contentPadding = 0f;
  6.                                 else if (contentPadding > 0.999f) contentPadding = 1f;
  7.                                 sb.barSize = 1f - contentPadding;
  8.                         }
@Samuraisa: Content size should always be smaller than the scroll view size. You should not rely on floating point precision like that. Leave some padding there instead.

Samuraisa

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 15
    • View Profile
Re: Bug in Scroll bar with Scroll view
« Reply #5 on: March 26, 2014, 02:50:56 AM »
If I leave some padding, than I can scroll list for that padding size, but I don't need that if I haven't enough items to scroll even if it is 1px scrolling. I know we are talking about float 3d-object dimensions, but in that case they are represent pixels, right? The pixels are integer concept, so why do not compare the rounded integer values here?
If I'm not right I already invented a workaround for this case, I just want to fully understand concept for myself ;)

Aleksandr

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: Bug in Scroll bar with Scroll view
« Reply #6 on: March 26, 2014, 03:22:16 AM »
@ArenMook:
I test code   
 if (contentPadding < 0.001f) contentPadding = 0f;
 else if (contentPadding > 0.999f) contentPadding = 1f;
 sb.barSize = 1f - contentPadding;
Incorrect behavior is present. (size was <1)

рow to check the condition  (else if (contentPadding > 0.999f) contentPadding = 1f;)?
In my version, I changed the value of the constant 0.01 to 0.1. And it works perfectly.

 protected void UpdateScrollbars(UIProgressBar slider, float contentMin, float contentMax, float contentSize, float viewSize, bool inverted)
    {
        if (slider == null)
            return;

        mIgnoreCallbacks = true;
        if (viewSize < contentSize)
        {
            contentMin = Mathf.Clamp01(contentMin / contentSize);
            contentMax = Mathf.Clamp01(contentMax / contentSize);

            var contentPadding = contentMin + contentMax;
            slider.value = inverted ? ((contentPadding > 0.001f) ? 1f - contentMin / contentPadding : 0f) :
                                      ((contentPadding > 0.001f) ? contentMin / contentPadding : 1f);

            var sb = slider as UIScrollBar;
            if (sb != null) sb.barSize = 1f - contentPadding;
        }
        else
        {
            contentMin = Mathf.Clamp01(-contentMin / contentSize);
            contentMax = Mathf.Clamp01(-contentMax / contentSize);

            var contentPadding = contentMin + contentMax;
            slider.value = inverted ? ((contentPadding > 0.001f) ? 1f - contentMin / contentPadding : 0f) :
                                      ((contentPadding > 0.001f) ? contentMin / contentPadding : 1f);

            if (contentSize > 0)
            {
                contentMin = Mathf.Clamp01(contentMin / contentSize);
                contentMax = Mathf.Clamp01(contentMax / contentSize);
                contentPadding = contentMin + contentMax;
            }

            var sb = slider as UIScrollBar;
            if (sb != null)
            {
                contentPadding = (contentPadding < 0.1f) ? 0 : 1;
                sb.barSize = 1f - contentPadding;
            }

        }
        mIgnoreCallbacks = false;
    }




ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Bug in Scroll bar with Scroll view
« Reply #7 on: March 26, 2014, 03:26:43 AM »
Again... you are forcing the scroll bar to either be completely full (size 1) or completely empty (size 0). How is this a fix? The scroll bar's size is supposed to change, reflecting the size of the content compared to the size of the scroll view. You are completely breaking that functionality.

Aleksandr

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: Bug in Scroll bar with Scroll view
« Reply #8 on: March 26, 2014, 04:47:56 AM »
Аpparently I did not quite understand the whole situation.

 if (contentPadding < 0.001f) contentPadding = 0f;
    else if (contentPadding > 0.999f) contentPadding = 1f;
 sb.barSize = 1f - contentPadding;

 Delta 0.001f is too small. If element count < 3 (example 11) is the ability to move elements by scroll bar.
 So works better :)
            var sb = slider as UIScrollBar;
            if (sb != null)
            {
                if (contentPadding < 0.1f) contentPadding = 0f;
                else if (contentPadding > 0.999f) contentPadding = 1f;
                sb.barSize = 1f - contentPadding;
            }

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Bug in Scroll bar with Scroll view
« Reply #9 on: March 26, 2014, 07:20:49 PM »
This value is percentage-based, so 0.1 effectively means 10%. That's actually a lot, especially with a long scroll bar.

Aleksandr

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: Bug in Scroll bar with Scroll view
« Reply #10 on: March 26, 2014, 11:19:58 PM »
What will be the final decision on this issue ?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Bug in Scroll bar with Scroll view
« Reply #11 on: March 27, 2014, 10:22:06 PM »
Yes. I don't like hacks, and this is exactly what it is. It doesn't address the real reason why there is a few pixel difference that translates to a small number. I'd rather find the reason than add magic numbers.