Tasharen Entertainment Forum

Support => NGUI 3 Documentation => Topic started by: ArenMook on November 22, 2013, 07:14:58 PM

Title: UIPopupList
Post by: ArenMook on November 22, 2013, 07:14:58 PM
Overview

Attaching a UIPopupList script to a button (http://www.tasharen.com/forum/index.php?topic=6708) will bring up a list of options for you to choose from.

(http://www.tasharen.com/ngui/uipopuplist.jpg)

To create a popup list with a set of options that will be shown when you click on some button, first add the UIPopupList script to it and specify the Atlas and Font options. You will also likely want to choose specific sprites to be used for the Background and the Highlight. Background is the sprite used to create a background behind the popup list's item selection, and the Foreground is the sprite used to highlight the currently selected option.

To specify different options for your Popup List, simply enter them in the Options box. It's a multi-line text box, and each line you add to it will create a new entry in the list. So if you wanted to have 3 different options -- "First", "Second" and "Third" -- you would enter them like so:
  1. First
  2. Second
  3. Third

The Font section defines what font is going to be used by labels created by the popup list. In the picture above, first, second and third option labels were all created with the "Arimo20" font specified in the inspector. Depending on the type of font used (bitmap or dynamic), you will be able to change the Font Size and -- if using a dynamic font -- Font Style. You can also choose the Text Color that will tint the text as well as the Padding in between of your text and the border created using the Background sprite from the Atlas section.

If you don't want the popup list to animate as it appears, but simply want it to appear and disappear as needed, uncheck the Animated option.

If you want the text options to be localized using the Localization System, check the Localized checkbox.

In the OnValueChange section you can specify a function that will be called when a value gets chosen in the Popup List. If you've added the label somewhere, you can easily reference its SetCurrentSelection function, and the label's value will show the Popup List's selection. To do this, drag & drop the Label's game object into the Notify field and then choose the UILabel.SetCurrentSelection function from the drop-down list.

To add a change listener via code, use the EventDelegate.Add function:
  1. EventDelegate.Add(popupList.onChange, YourFunction);
...where YourFunction is of void FuncName(void) type:
  1. void YourFunction ()
  2. {
  3.     Debug.Log("Selection: " + UIPopupList.current.value);
  4. }

Pro-Tip

To make a more practical popup list -- a Drop-Down List, reference the button's label in the OnValueChange field and choose its UILabel.SetCurrentSelection method. After doing so, the label's text will automatically update itself when you choose an item from the list.

Class Documentation

http://tasharen.com/ngui/docs/class_u_i_popup_list.html

If you have a question regarding this component or would like me to clarify something, just post a reply here.
Title: Re: UIPopupList
Post by: Messu on November 27, 2013, 11:13:10 AM
Hello,
I'm currently using NGUI in our project. We just updated version form 2.X to 3.X of NGUI and I'm having some problems with that component.
The Drop Down list is oversized on Width.

Moreover, I don't know how to use each parameter, could you put some details about it in the Documentation (or here) ?

I also would like to ask for at least one feature : the possibility for the drop down to be configurable as the label alignment.

Finally, I apologize for my poor English as I'm French.

By the way, thank you for your great work.
Title: Re: UIPopupList
Post by: ArenMook on November 28, 2013, 04:00:59 PM
The selection is offset so much along the X because of your X Padding value under the Font section. Your highlight sprite also seems to be missing a border, which is why there is no offset between the left edge of the highlight and the text. The thicker the border of the sprite, the more offset it will be.
Title: Re: UIPopupList
Post by: Messu on November 29, 2013, 04:55:58 AM
I'm not sure what I should answer to your advices.
I got it about the padding but it's clearly not the main issue here.
Actually, the Sprite I'm using is the same for popup background, drop-down list background and highlight. The Sprite have a top and bottom border but no left and right border : it is intended to keep not horizontal lines on top and bottom of the sprite.
I use it as a Sliced Sprite.
I don't know if it has an impact but I also use an UIStretch and it changes the scale of many objects however the patch note says that the UIwidgets are no longer using the scale... that's why I'm a bit confused.
The main thing I'm not getting is why the popup list (at least in it's previous version) is not replicating the Label behaviour (I understand that now there is no direct link with the label so not sure it can be done now).

To fix my issue, I guess I will switch to another type of interaction to change the language of my app.
By the way, thank you for your answer.
Title: Re: UIPopupList
Post by: ArenMook on November 29, 2013, 10:38:03 AM
Why not give it a left and right border value? They are used to position the highlight as well.
Title: Re: UIPopupList
Post by: Messu on December 02, 2013, 09:38:18 AM
Finally, I solved my problem : I do not use UIPopup and I created an other ergonomic solution.
The point about left and right values is that if I put left and right values, my background picture will keep corners at the same size and the part between them will be stretched. What I wanted was to stretch the top and the bottom of my picture horizontally but keep the vertical size and stretch horizontally and vertically the center of my picture. In that way, I can have a background with a inclined line border as top and bottom borders but with vertical left and right sides.
Title: Re: UIPopupList
Post by: knifesk on December 20, 2013, 12:10:44 PM
what about the following scenario: I have many options... fetched from a Database... so, depending on what is returned from DB the dropdown is shorter, taller... sometimes options are that many that when popup opens it wont fit the screen. Is there any way to make it scrollable?
Title: Re: UIPopupList
Post by: ArenMook on December 20, 2013, 12:37:33 PM
Not with this component, no. I advise dynamically creating a scroll view (or better yet -- instantiating a prefab of one), and populating it with your entries. Make it show when you need it, hide it when you don't. You don't need to be bound by what UIPopupList provides. It's simply a convenience script.
Title: Re: UIPopupList
Post by: knifesk on December 23, 2013, 07:36:17 AM
Ok, That was what I thought in the first place.. but I read in an old post somewhere around the forum that this was a pending feature, just asking in case it were already implemented.

Thanks.. I'll maybe share the prefab.

Cheers
Title: Re: UIPopupList
Post by: rptts on March 05, 2014, 06:02:30 AM
I was having the same problem as Messu and I solved the situation by making some changes in the UIPopupList.cs

Line 683:
  1. x = Mathf.Max(x, lbl.printedSize.x * dynScale);

Line 700:
  1. x = Mathf.Max(x, bounds.size.x - (bgPadding.x + padding.x) * 2f);

I only tested with bitmap font, and I didn't made an exhaustive examination to the UIPopupList.cs, so I'm not sure that it is 100% bulletproof, but so far, so good.
Title: Re: UIPopupList
Post by: Morgoth on April 20, 2014, 11:22:37 AM
Is there an easy way to get the index number of the selected item as int?
Title: Re: UIPopupList
Post by: ArenMook on April 20, 2014, 05:30:14 PM
No, there are no numbers, but you can treat your entries as such. For example the following options:
  1. OPTION 01
  2. OPTION 02
  3. OPTION 03
Then in your Localization file add these entries:
  1. "OPTION 01","First Option"
  2. "OPTION 02","Second Option"
  3. "OPTION 03","Third Option"
Your callback function will be receiving "OPTION 01", but your user will see "First Option".
Title: Re: UIPopupList
Post by: Morgoth on April 20, 2014, 09:56:21 PM
I think I got a passable solution,
added a public int mIndex variable to the class which is set at the start of the Select function to mIndex = mLabelList.IndexOf(lbl);

edit:
better solution: set mIndex in TriggerCallbacks to mIndex = items.IndexOf(mSelectedItem);
Title: Re: UIPopupList
Post by: Edy on June 07, 2014, 06:22:34 AM
Is there an easy way to get the index number of the selected item as int?

  1. int selectedIndex = UIPopupList.current.items.IndexOf(UIPopupList.current.value);
Title: Re: UIPopupList
Post by: kruncher on July 25, 2014, 07:53:31 PM
It would be very useful if we could either a) get the zero-based index of the selected item or b) associate a private identifier with each item.

The display label isn't always unique which makes it impossible to determine which item has been selected...

For instance, in HTML you can have this:
  1. <select>
  2.     <option value="private-value-1">Visible Label 1</option>
  3.     <option value="private-value-2">Visible Label 2</option>
  4. </select>
  5.  
Title: Re: UIPopupList
Post by: kruncher on July 25, 2014, 08:02:34 PM
I am also having an issue with colliders. I have used the option Extras | Switch to 2D Colliders with the "Control - Colored Popup List" prefab. The button part of the control shows the popup fine; but the item entries cannot be selected.

Am I doing something wrong? Perhaps I have forgotten to configure something somewhere?

Edit 1: It seems the 2D box colliders reappear when fiddling with "Size Y" value of the box collider and work for one go. The next time the popup is shown they cease to work again...

Edit 2: Increasing the font padding from Y=4 to Y=8 seems to do the trick...
Title: Re: UIPopupList
Post by: ArenMook on July 26, 2014, 03:51:50 AM
Seems to work fine here.

1. New scene.
2. Dragged in the Colored Popup List.
3. NGUI menu -> Extras -> Switch to 2D Colliders
4. Hit Play, click on the popup list, select items inside. Works as expected.
Title: Re: UIPopupList
Post by: kruncher on July 26, 2014, 06:48:54 AM
Interesting, since restarting Unity the problem no longer occurs in the original scene, neither does it occur upon creating new popup controls.

I was able to reproduce this yesterday without issue...

Nether-mind, it seems that it has sorted itself out! Thanks.
Title: Re: UIPopupList
Post by: crusty210 on August 07, 2014, 08:11:44 PM
I am having an issue where when I select a value from the list the list closes but the instance of Drop-Down list still remains in the hierarchy. Now when I click the popup again, another Drop-Down list instance is created in the hierarchy. Is there a way to destroy the previous instance?

I am using the following code to add items to the popup list

  1. nonExpandedCountriesPopup.GetComponent<UIPopupList>().items = masterHandler.GetComponent<MasterHandlerL1>().MasterCountries;

  1. MasterCountries
is the list that I am adding to the popup under the GameObject
  1. nonExpandedCountriesPopup

I tried using
  1. nonExpandedCountriesPopup.GetComponent<UIPopupList>().Close();
to close (destroy) the instance but it doesn't work

Any clues?
Title: Re: UIPopupList
Post by: ArenMook on August 08, 2014, 09:11:38 AM
Popup list closes automatically, and there is nothing left when it's closed. If something is left in your case, check to see what you're doing different.

Also, you are assigning items incorrectly. You should not be assigning the entire list. You should be adding items to that list instead.
Title: Re: UIPopupList
Post by: treydavis76 on August 27, 2014, 02:59:37 PM
I have a popup list with 38 buttons in the 'Options' box.  How do I apply script to those individual buttons in the list?  (Each button will make the camera move to a specific location in the scene).
I have javascript created, that controls the movement, but I need to know how to apply this script to those buttons in the dropdown list.
Thanks!
Title: Re: UIPopupList
Post by: ArenMook on August 28, 2014, 09:43:51 PM
Drop-down list doesn't have buttons. It creates its content programmatically, and it's just a bunch of labels inside a sliced sprite. You would need to create a custom script to handle what you want done.
Title: Re: UIPopupList
Post by: treydavis76 on September 02, 2014, 12:02:21 PM
Being very new to scripting in Unity, how would I go about writing a script for the options inside of the dropdown menu?  Basically for each one of the options, I want something to happen when I select an option.  At this point, I'll be happy if I can get an option to just show an object in the scene (like an arrow or something) when I click on it.
Title: Re: UIPopupList
Post by: ArenMook on September 02, 2014, 12:38:44 PM
You can set an OnChange delegate with the popup list. What you do inside that function is up to you.
Title: Re: UIPopupList
Post by: col000r on October 13, 2014, 11:14:44 AM
Is there an easy way to set the current selection from script?

I'm trying to do dropdown.value = "One of the available options"; but it doesn't seem to work.
Title: Re: UIPopupList
Post by: nicloay on October 14, 2014, 12:44:57 AM
Is there an easy way to set the current selection from script?

I'm trying to do dropdown.value = "One of the available options"; but it doesn't seem to work.

Hi, I've just faced the same problem, I had an event handler which stored selected data. and the problem was that initially UIPopupList  set default value from inspector, and my handler pick this value and rewrites actual value.
The solution was to unsubscribe from onChange method in Start and subscribe back after initial default value performed.

  1.         void Start ()
  2.         {              
  3.                 UIPopupList popup = GetComponentInChildren<UIPopupList>();
  4.                 EventDelegate.Remove(popup.onChange, new EventDelegate(this,"OnDifficultyChange"));
  5.                 popup.value = UserData.Instance.Difficulty.ToString();
  6.                 EventDelegate.Add(popup.onChange, new EventDelegate(this,"OnDifficultyChange"));
  7.         }
  8.  
  9.         public void OnDifficultyChange(){
  10.                 UserData.Instance.Difficulty = (Difficulty) System.Enum.Parse(typeof(Difficulty),  GetComponentInChildren<UIPopupList>().value);
  11.                 UserData.Instance.SaveChanges();
  12.         }
  13.  
  14.  

p.s. Probably there is more easy method to subscribe and unsubscribe from events.
Title: Re: UIPopupList
Post by: ArenMook on October 14, 2014, 03:52:16 PM
Is there an easy way to set the current selection from script?

I'm trying to do dropdown.value = "One of the available options"; but it doesn't seem to work.
UIPopupList.value is it -- provided the "One of the available options" is a valid item that can be found in UIPopupList.items.
Title: Re: UIPopupList
Post by: chiphuc113 on May 10, 2015, 10:33:34 AM
Hello everyone right now i have a error with uipopuplist.

when i change my scalingstyle in uiroot to constrained. UIPopupMenu will show wrong position when i change position of Uipopuplist go to the top-left of the screen. I don't know what going on here. Have anyone can help me out.

Thank a lots.
Title: Re: UIPopupList
Post by: jfperusse_indie on May 14, 2015, 12:18:16 PM
Hi ArenMook,

When using the UIPopupList, we end up with buttons that are way too large (currently using SciFi Font - Normal, Font Size 80).

The problem seems to be in UIPopupList.cs, "public void Show ()", here:

  1. x = Mathf.Max(x, (max.x - min.x) * dynScale - (bgPadding.x + padding.x) * 2f);

It seems like dynScale should not be used here since min/max already used the proper rendered size of the text.

Removing dynScale makes our button fit the text perfectly.

Could you confirm that this is the proper fix? We are using the latest version of NGUI (3.8.2).

Thanks!
Title: Re: UIPopupList
Post by: ArenMook on May 14, 2015, 06:18:31 PM
Seems reasonable to me. I'll change it on my end and post again if I notice any adverse effects.
Title: Re: UIPopupList
Post by: Paul on October 27, 2015, 03:23:14 PM
I've added a resolution dropdown list for a PC game with keyboard, mouse & controller input, however when using the arrow keys or controller to navigate the menu, I noticed the onValueChange callback gets called on each navigation.

Is it possible to instead treat this navigation like mouse over and only perform onValueChange when the user submits their choice (via the enter key or 'A' controller button for example)?

I'm currently changing the application's resolution in the onValueChange callback which causes jarring behavior when using the keyboard/controller. Aside from adding an 'Apply Changes' button to the options screen, I was wondering if there was another way.

Thanks!!
Title: Re: UIPopupList
Post by: ArenMook on October 29, 2015, 07:17:29 AM
You could do it, but you'd need to modify the popup list's functionality... unfortunately I don't have any simple suggestions for you off the top of my head.

Although you could simply check if the UIPopupList.isOpen in your callback function to see if it should be responding to state changes or not.
Title: Re: UIPopupList
Post by: Paul on November 20, 2015, 12:13:12 AM
Thanks for the UIPopupList.isOpen tip -- I wasn't aware of that.

I ended up modifying UIPopupList by adding another EventDelegate that only fires after a selection has been made. Not the prettiest code, but it was a small change nonetheless. =)
Title: Re: UIPopupList
Post by: Benzino07 on January 22, 2016, 10:26:34 AM
Is there anyway to specify a non-UIAtlas sprite for the drop down?
Title: Re: UIPopupList
Post by: ArenMook on January 25, 2016, 10:56:24 PM
You can just change the UISprite's references within UIPopupList to something else if you like. Assuming you want to use UI2DSprites?

Edit: I've gone ahead and added support for 2D sprites. Replace UIPopupList.cs and UIPopupListInspector.cs files with these.
Title: Re: UIPopupList
Post by: Benzino07 on January 26, 2016, 05:00:25 AM
You can just change the UISprite's references within UIPopupList to something else if you like. Assuming you want to use UI2DSprites?

Edit: I've gone ahead and added support for 2D sprites. Replace UIPopupList.cs and UIPopupListInspector.cs files with these.

I had gone ahead and rolled my own solution, but this is much better, thanks! One modification I did make which I think would be useful to add is the ability to set the drop-down list panel's sorting layer in the UIPopuplist inspector, as it currently defaults to "Default" which may be behind the sorting layer of the panel which creates the drop-down list.

Anyway, thanks again!
Title: Re: UIPopupList
Post by: Benzino07 on June 22, 2016, 06:13:50 AM
Hey, I've noticed an issue with the Popuplist inspector. If I remove the reference to an UIAtlas, the options appear to use individual sprites like you implemented above. However, if I select another object, and then go back to the UIPopuplist, the reference to the UIAtlas is returned and is no longer null. The same happens after resetting the component.

I've uploaded a gif (http://makeagif.com/i/XNjbeT) to demonstrate the issue.

I'm on version 3.9.9 but this issue may have been happening before, I've only noticed it now
Title: Re: UIPopupList
Post by: ArenMook on June 24, 2016, 02:00:35 AM
Nice catch, thanks. You can fix it by getting rid of the part that sets it in the OnEnable function of UIPopupListInspector:
  1.         void OnEnable ()
  2.         {
  3.                 SerializedProperty bit = serializedObject.FindProperty("bitmapFont");
  4.                 mType = (bit.objectReferenceValue != null) ? FontType.Bitmap : FontType.Dynamic;
  5.                 mList = target as UIPopupList;
  6.  
  7.                 if (mList.ambigiousFont == null)
  8.                 {
  9.                         mList.ambigiousFont = NGUISettings.ambigiousFont;
  10.                         mList.fontSize = NGUISettings.fontSize;
  11.                         mList.fontStyle = NGUISettings.fontStyle;
  12.                         EditorUtility.SetDirty(mList);
  13.                 }
  14.  
  15.                 //if (mList.atlas == null)
  16.                 //{
  17.                 //    mList.atlas = NGUISettings.atlas;
  18.                 //    mList.backgroundSprite = NGUISettings.selectedSprite;
  19.                 //    mList.highlightSprite = NGUISettings.selectedSprite;
  20.                 //    EditorUtility.SetDirty(mList);
  21.                 //}
  22.         }
Title: Re: UIPopupList
Post by: Benzino07 on June 24, 2016, 03:48:53 AM
Great, thanks!
Title: Re: UIPopupList
Post by: tree1891 on September 23, 2016, 02:57:58 AM
I have used UIPopupList.value member for select via code.
But after call it, UIPopupList.value is null because of mSelectedItem = null in Set function.
Then how to get current selected item later?
Title: Re: UIPopupList
Post by: devomage on September 23, 2016, 03:38:45 PM
search the forums  :P

It's intentional. The popup list only has a value during its callback function. I've mentioned this on several occasions in the past. If you want to store this value, do just that.
  1. public string savedValue;
  2.  
  3. void Start ()
  4. {
  5.     var popup = GetComponent<UIPopupList>();
  6.     EventDelegate.Add(popup.onChange, delegate () { savedValue = popup.value; });
  7. }
Title: Re: UIPopupList
Post by: kendro on December 04, 2016, 10:02:05 PM
I countered an issue in the popuplist after upgrading to 3.10.2 (from 3.9.7).  If you select the FirstOption then nothing happens.  If you select either the SecondOption or ThirdOption then the event fires... and only then the next time you click FirstOption it will fire the event.

I have uploaded a gif (http://makeagif.com/qFiY6E) to demonstrate the issue.

I haven't updated yet to the latest 3.11.x, but did not notice anything in release notes in reference to this bug.
Title: Re: UIPopupList
Post by: ArenMook on December 04, 2016, 10:28:35 PM
The event only fires if you don't already have selection set to the same thing. By default the popup list has no selection. Did you set it manually yourself?
Title: Re: UIPopupList
Post by: kendro on December 05, 2016, 05:39:07 PM
How do you set the popup list selection to "nothing" then... so that no matter what you select in the list it always fires the onChange event. The use case would be like a popup menu... so you would not have a "default or current selection" in that case.
Title: Re: UIPopupList
Post by: ArenMook on December 06, 2016, 05:58:48 AM
That's exactly how it works though. The popup list has no selection explicitly for that reason -- so you can select the same thing repeatedly. Once the popup list is closed, the selection is cleared to null. Before the change it wasn't possible to select the same thing repeatedly, as selection value persisted from one time you opened the popup list to the next.
Title: Re: UIPopupList
Post by: kendro on December 07, 2016, 08:43:09 PM
Hi Aren, thanks for the replies. I just noticed that I wasn't clear with describing the issue i encountered. I didn't notice that the gif trimmed the whole video.

My code is just a simple Debug.Log for the UIPopuplist.current.value for every selection change, this is using NGUI 3.10.2.
The issue is, on the first drop-down list Show(), I couldn't select the FirstOption on first click (can be shown in the video where nothing displays in the console).

Please see video link here (https://drive.google.com/open?id=0B2sOebfV0O5EWGJWMXZGWDIyRGM).

I have also attached the unity package.

I didn't have any problems with using NGUI 3.9.7, this occurred after updating to 3.10.x - (im using Unity 5.4.x).
Title: Re: UIPopupList
Post by: ArenMook on December 10, 2016, 10:27:13 AM
Thanks. I fixed it in 3.11.1 that I just pushed live.
Title: Re: UIPopupList
Post by: kendro on December 10, 2016, 10:38:43 AM
Cool! Thanks!