Author Topic: UILabel Shrink  (Read 8301 times)

nah0y

  • Sr. Member
  • ****
  • Thank You
  • -Given: 1
  • -Receive: 2
  • Posts: 430
  • \o/
    • View Profile
UILabel Shrink
« on: April 03, 2013, 12:28:10 PM »
Hi,

With the latest update (2.5.1), you've added the possibility to shrink a label if the text is larger than the maxSize.
It's working great, but... only for single line labels.

Let's say I have a label, that has a max size of 250px.
If I want this label, to stop at the end of the 250px and go on on the next line, I just do nothing. It works (ok, normal).
If I want it to stop, and takes only 4 lines, I should just set the max lines to 4, and the text should shrink just a little, so that it fits in 4 lines. Right now, the problem is that, if you shrink it, it will try to fit everything on a single line, and display a really tiny label, even if I want it to be on 4 lines :(

Is there any way to fix that ?

Thanks !

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UILabel Shrink
« Reply #1 on: April 03, 2013, 05:10:40 PM »
There is if you code it! :P

I wrote this feature for single line labels.

sandolkakos

  • Newbie
  • *
  • Thank You
  • -Given: 16
  • -Receive: 1
  • Posts: 17
    • View Profile
Re: UILabel Shrink
« Reply #2 on: April 04, 2013, 12:34:20 AM »
This is an amazing feature.

Is there any chance to you add support to multiple lines?

laurentl

  • Full Member
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 188
    • View Profile
    • McDROID
Re: UILabel Shrink
« Reply #3 on: April 04, 2013, 03:32:51 AM »
I could use that, where is it ?

Hi,

With the latest update (2.5.1), you've added the possibility to shrink a label if the text is larger than the maxSize.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UILabel Shrink
« Reply #4 on: April 04, 2013, 04:27:32 AM »
@sandolkakos: In the future, perhaps.

@laurentl: It's a checkbox on the UILabel.

laurentl

  • Full Member
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 188
    • View Profile
    • McDROID
Re: UILabel Shrink
« Reply #5 on: April 04, 2013, 04:49:06 AM »
Fresh off the foundry :)
Very nice !

sandolkakos

  • Newbie
  • *
  • Thank You
  • -Given: 16
  • -Receive: 1
  • Posts: 17
    • View Profile
Re: UILabel Shrink
« Reply #6 on: April 11, 2013, 02:45:59 AM »
@ArenMook
I am using the Shrink to Fit in a Object that i need your size be not Pixel-perfect. Then i modified the UILabel and UILabelInspector classes to add a new field in Inspector to me set the Maximum font size when Shrink To Fit is being used.
Maybe this can help other peoples, or if you want put this in the Official Package, it would amazing :)

Modifications in the UILabel class:
Add in line 33:
  1.         [HideInInspector][SerializeField] int mShrinkMaxFontSize = 10; // Default value, but the user need set manually
  2.  

Add in Line 577:
  1.         /// <summary>
  2.         /// Maximum font size when Shrink To Fit is being used.
  3.         /// </summary>
  4.  
  5.         public int shrinkMaxFontSize
  6.         {
  7.                 get
  8.                 {
  9.                         return mShrinkMaxFontSize;
  10.                 }
  11.                 set
  12.                 {
  13.                         if (mShrinkMaxFontSize != value)
  14.                         {
  15.                                 mShrinkMaxFontSize = value;
  16.                                 hasChanged = true;
  17.                         }
  18.                 }
  19.         }
  20.  
  21.  

Modify Lines 526-537:
  1.                         // We want to shrink the label (when it doesn't fit)
  2.                         if (scale > 0f)
  3.                         {
  4.                                 float maxSize = (float)mMaxLineWidth / shrinkMaxFontSize;
  5.                                 scale = (mSize.x > maxSize) ? (maxSize / mSize.x) * shrinkMaxFontSize : shrinkMaxFontSize;
  6.                                 cachedTransform.localScale = new Vector3(scale, scale, 1f);
  7.                         }
  8.                         else
  9.                         {
  10.                                 mSize.x = 1f;
  11.                                 cachedTransform.localScale = new Vector3(shrinkMaxFontSize, shrinkMaxFontSize, 1f);
  12.                         }
  13.  

Modifications in the UILabelInspector class:
Add in Line 66:
  1.                 if (shrinkToFit)
  2.                 {
  3.                         GUILayout.BeginHorizontal();
  4.                         int scale = EditorGUILayout.IntField("Max Font Scale", mLabel.shrinkMaxFontSize, GUILayout.Width(120f));
  5.                         GUILayout.Label("pixels");
  6.                         GUILayout.EndHorizontal();
  7.                         if (len != mLabel.shrinkMaxFontSize) { RegisterUndo(); mLabel.shrinkMaxFontSize = scale; }
  8.                 }
  9.  
« Last Edit: April 11, 2013, 02:52:40 AM by sandolkakos »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UILabel Shrink
« Reply #7 on: April 11, 2013, 09:08:32 PM »
Nice, but ideally it should just overwrite how the "max lines" property is treated, not introduce a new variable.

sandolkakos

  • Newbie
  • *
  • Thank You
  • -Given: 16
  • -Receive: 1
  • Posts: 17
    • View Profile
Re: UILabel Shrink
« Reply #8 on: April 11, 2013, 10:13:31 PM »
Nice, but ideally it should just overwrite how the "max lines" property is treated, not introduce a new variable.
I did this because i need use a Label with smaller size that Original Font Size.
i.e., my font is Arial 35, and i need create a Label with your size 25. But if i use the "Shrink to Fit", and the Text is changed, then the Shrink System can re-size my Label to 35, but i want the Label with the max size 25 :(

Remembering that here these modifications are working successful. But when you release a new version of NGUI, i will lose my modifications :(

Sorry for my english.

NaxIonz

  • Jr. Member
  • **
  • Thank You
  • -Given: 3
  • -Receive: 0
  • Posts: 70
    • View Profile
Re: UILabel Shrink
« Reply #9 on: April 23, 2013, 11:06:05 AM »
Yeah, I think I need to steal this code.

"Shrink to fit" is pretty much useless right now. It only works on single lines, and if the text DOES fit, it scales UP?????

NaxIonz

  • Jr. Member
  • **
  • Thank You
  • -Given: 3
  • -Receive: 0
  • Posts: 70
    • View Profile
Re: UILabel Shrink
« Reply #10 on: April 23, 2013, 11:44:53 AM »
Ahhhhhhhhh.... MUCH better now  8)

  1. void ProcessText ()
  2.         {
  3.                 mChanged = true;
  4.                 hasChanged = false;
  5.                 mLastText = mText;
  6.                 mProcessedText = mText;
  7.  
  8.                 if (mPassword)
  9.                 {
  10.                         string hidden = "";
  11.  
  12.                         if (mShowLastChar)
  13.                         {
  14.                                 for (int i = 0, imax = mProcessedText.Length - 1; i < imax; ++i) hidden += "*";
  15.                                 if (mProcessedText.Length > 0) hidden += mProcessedText[mProcessedText.Length - 1];
  16.                         }
  17.                         else
  18.                         {
  19.                                 for (int i = 0, imax = mProcessedText.Length; i < imax; ++i) hidden += "*";
  20.                         }
  21.                         mProcessedText = mFont.WrapText(hidden, mMaxLineWidth / cachedTransform.localScale.x,
  22.                                 mMaxLineCount, false, UIFont.SymbolStyle.None);
  23.                 }
  24.         else
  25.         {
  26.             if (mMaxLineWidth > 0)
  27.             {
  28.                 if (mShrinkToFit)
  29.                 {
  30.                     if (mMaxLineCount > 1)
  31.                     {
  32.                         mProcessedText = mFont.WrapText(mProcessedText, mMaxLineWidth / cachedTransform.localScale.x, mMaxLineCount, mEncoding, mSymbols);
  33.                     }
  34.                     else
  35.                     {
  36.                         mProcessedText = mFont.WrapText(mProcessedText, 100000f, mMaxLineCount, mEncoding, mSymbols);
  37.                     }
  38.                 }
  39.                 else
  40.                 {
  41.                     mProcessedText = mFont.WrapText(mProcessedText, mMaxLineWidth / cachedTransform.localScale.x, mMaxLineCount, mEncoding, mSymbols);
  42.                 }
  43.             }
  44.             else if (mMaxLineCount > 0)
  45.             {
  46.                 mProcessedText = mFont.WrapText(mProcessedText, 100000f, mMaxLineCount, mEncoding, mSymbols);
  47.             }
  48.         }      
  49.  
  50.                 float scale = Mathf.Abs(cachedTransform.localScale.x);
  51.                 mSize = !string.IsNullOrEmpty(mProcessedText) ? mFont.CalculatePrintedSize(mProcessedText, mEncoding, mSymbols) : Vector2.one;
  52.  
  53.                 if (mShrinkToFit && mMaxLineWidth > 0)
  54.                 {
  55.             if (mMaxLineCount > 1)
  56.             {
  57.                 int length = mText.Length;                
  58.                 while (mProcessedText.Length < length && transform.localScale.x > MIN_SCALE)
  59.                 {
  60.                     cachedTransform.localScale = cachedTransform.localScale * 0.99f;
  61.                     ProcessText();
  62.                 }
  63.             }
  64.             else
  65.             {
  66.                 // We want to shrink the label (when it doesn't fit)
  67.                 if (scale > 0f)
  68.                 {
  69.                     float maxSize = (float)mMaxLineWidth / mFont.size;
  70.                     scale = (mSize.x > maxSize) ? (maxSize / mSize.x) * mFont.size : mFont.size;
  71.                     scale = Mathf.Min(mDefaultScale, scale);
  72.                     scale = Mathf.Max(scale, MIN_SCALE);
  73.                     cachedTransform.localScale = new Vector3(scale, scale, 1f);
  74.                 }
  75.                 else
  76.                 {
  77.                     mSize.x = 1f;
  78.                     cachedTransform.localScale = new Vector3(mFont.size, mFont.size, 1f);
  79.                 }
  80.             }
  81.                 }
  82.                 else
  83.                 {
  84.                         mSize.x = Mathf.Max(mSize.x, (scale > 0f) ? lineWidth / scale : 1f);
  85.                 }
  86.  
  87.                 mSize.y = Mathf.Max(mSize.y, 1f);
  88.         }
  89.  
« Last Edit: April 23, 2013, 02:41:15 PM by NaxIonz »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UILabel Shrink
« Reply #11 on: April 23, 2013, 03:36:31 PM »
As I advised in some random email (this is why I REALLY hate answering private emails/PMs! -- they don't help anyone else!) -- when you want to use auto-shrink, but cap it at a specific size, add a parent object to the label and scale the parent object instead. For example if you had size 48 font and wanted a size 32 label do this:

GameObject (scale of 32 / 48)
- Label (shrink to fit)

No code modifications needed.

sandolkakos

  • Newbie
  • *
  • Thank You
  • -Given: 16
  • -Receive: 1
  • Posts: 17
    • View Profile
Re: UILabel Shrink
« Reply #12 on: April 23, 2013, 04:14:50 PM »
As I advised in some random email (this is why I REALLY hate answering private emails/PMs! -- they don't help anyone else!)
I also agree.

when you want to use auto-shrink, but cap it at a specific size, add a parent object to the label and scale the parent object instead. For example if you had size 48 font and wanted a size 32 label do this:

GameObject (scale of 32 / 48)
- Label (shrink to fit)

No code modifications needed.
Perfect solution :)

jeldrez

  • Sr. Member
  • ****
  • Thank You
  • -Given: 8
  • -Receive: 4
  • Posts: 352
    • View Profile
Re: UILabel Shrink
« Reply #13 on: May 22, 2013, 11:27:38 PM »
Ahhhhhhhhh.... MUCH better now  8)

  1. void ProcessText ()
  2.    {
  3.       mChanged = true;
  4.       hasChanged = false;
  5.       mLastText = mText;
  6.       mProcessedText = mText;
  7.  
  8.       if (mPassword)
  9.       {
  10.          string hidden = "";
  11.  
  12.          if (mShowLastChar)
  13.          {
  14.             for (int i = 0, imax = mProcessedText.Length - 1; i < imax; ++i) hidden += "*";
  15.             if (mProcessedText.Length > 0) hidden += mProcessedText[mProcessedText.Length - 1];
  16.          }
  17.          else
  18.          {
  19.             for (int i = 0, imax = mProcessedText.Length; i < imax; ++i) hidden += "*";
  20.          }
  21.          mProcessedText = mFont.WrapText(hidden, mMaxLineWidth / cachedTransform.localScale.x,
  22.             mMaxLineCount, false, UIFont.SymbolStyle.None);
  23.       }
  24.         else
  25.         {
  26.             if (mMaxLineWidth > 0)
  27.             {
  28.                 if (mShrinkToFit)
  29.                 {
  30.                     if (mMaxLineCount > 1)
  31.                     {
  32.                         mProcessedText = mFont.WrapText(mProcessedText, mMaxLineWidth / cachedTransform.localScale.x, mMaxLineCount, mEncoding, mSymbols);
  33.                     }
  34.                     else
  35.                     {
  36.                         mProcessedText = mFont.WrapText(mProcessedText, 100000f, mMaxLineCount, mEncoding, mSymbols);
  37.                     }
  38.                 }
  39.                 else
  40.                 {
  41.                     mProcessedText = mFont.WrapText(mProcessedText, mMaxLineWidth / cachedTransform.localScale.x, mMaxLineCount, mEncoding, mSymbols);
  42.                 }
  43.             }
  44.             else if (mMaxLineCount > 0)
  45.             {
  46.                 mProcessedText = mFont.WrapText(mProcessedText, 100000f, mMaxLineCount, mEncoding, mSymbols);
  47.             }
  48.         }      
  49.  
  50.       float scale = Mathf.Abs(cachedTransform.localScale.x);
  51.       mSize = !string.IsNullOrEmpty(mProcessedText) ? mFont.CalculatePrintedSize(mProcessedText, mEncoding, mSymbols) : Vector2.one;
  52.  
  53.       if (mShrinkToFit && mMaxLineWidth > 0)
  54.       {
  55.             if (mMaxLineCount > 1)
  56.             {
  57.                 int length = mText.Length;                
  58.                 while (mProcessedText.Length < length && transform.localScale.x > MIN_SCALE)
  59.                 {
  60.                     cachedTransform.localScale = cachedTransform.localScale * 0.99f;
  61.                     ProcessText();
  62.                 }
  63.             }
  64.             else
  65.             {
  66.                 // We want to shrink the label (when it doesn't fit)
  67.                 if (scale > 0f)
  68.                 {
  69.                     float maxSize = (float)mMaxLineWidth / mFont.size;
  70.                     scale = (mSize.x > maxSize) ? (maxSize / mSize.x) * mFont.size : mFont.size;
  71.                     scale = Mathf.Min(mDefaultScale, scale);
  72.                     scale = Mathf.Max(scale, MIN_SCALE);
  73.                     cachedTransform.localScale = new Vector3(scale, scale, 1f);
  74.                 }
  75.                 else
  76.                 {
  77.                     mSize.x = 1f;
  78.                     cachedTransform.localScale = new Vector3(mFont.size, mFont.size, 1f);
  79.                 }
  80.             }
  81.       }
  82.       else
  83.       {
  84.          mSize.x = Mathf.Max(mSize.x, (scale > 0f) ? lineWidth / scale : 1f);
  85.       }
  86.  
  87.       mSize.y = Mathf.Max(mSize.y, 1f);
  88.    }
  89.  


I've tested this and didn't work to me. It convert everything into 1 smaller line. =/

sandolkakos

  • Newbie
  • *
  • Thank You
  • -Given: 16
  • -Receive: 1
  • Posts: 17
    • View Profile
Re: UILabel Shrink
« Reply #14 on: May 23, 2013, 07:18:07 PM »

I've tested this and didn't work to me. It convert everything into 1 smaller line. =/
Use the ArenMook's solution. That is a perfect solution, and you dont need modify the NGUI Scripts.

when you want to use auto-shrink, but cap it at a specific size, add a parent object to the label and scale the parent object instead. For example if you had size 48 font and wanted a size 32 label do this:

GameObject (scale of 32 / 48)
- Label (shrink to fit)

No code modifications needed.