Jump to content

PopupDialog and the DialogGUI classes


Recommended Posts

On 5/23/2017 at 5:28 PM, sarbian said:

You compile for .NET 4.5 ?

Thanks! Switched target to 3.5 took care of KSP not loading the dll. My derp indeed.

 

Still no joy on grayed out button, though:

DialogGUIBase[] items = new DialogGUIBase[5];
items[0] = new DialogGUILabel("<size=15><b>"+pcm.name+"</b></size>" + (isTourist?"<size=10> (tourist)</size>":"") ,true,true);
items[1] = new DialogGUIButton("<size=14>"+txt_EVABtn+"</size>",delegate{onBtnEVA(pcm);},48,24,true,null);
if (isTourist) items[1].OptionEnabledCondition = ()=>false;
items[2] = new DialogGUIButton("x",delegate{Debug.Log("x");},()=>false,24,24,true);
items[3] = new DialogGUIButton("y",delegate{Debug.Log("y");},()=>{return false;},24,24,true);
items[4] = new DialogGUIButton("z",delegate{Debug.Log("z");},delegate {return false;},24,24,true);
DialogGUIHorizontalLayout h = new DialogGUIHorizontalLayout(false,false,0f,new RectOffset(4,0,0,0),TextAnchor.MiddleLeft,items);

x,y,z buttons specifying OptionEnabledCondition in three different ways in dialogGUIButton constructor; all three buttons remain enabled:

enabledcondition.png

 

----------

Edit: after further tests:
OptionEnabledCondition (and DismissOnSelect) do work properly, regardless of whether they were created along with the dialog box, or added later (as per @TaxiService example).

Reason why I couldn't get it to work is because I was shoehorning DialogGUI elements into CrewHatchDialog, which doesn't use the PopupDialog system.
Absent the "right" kind of dialog box, DismissOnSelect not working isn't that surprising, but I guess OptionEnabledCondition on standalone buttons was also too much to hope for.

Edited by cakepie
Link to comment
Share on other sites

On 2/4/2017 at 3:14 PM, HebaruSan said:
  • The UI elements have a tooltipText property, but I could not figure out how to make it display

@Morse explained how to do tooltips if you have a GameObject, and I was able to put tooltips on my DialogGUIButtons by waiting till their GameObjects are created (when the popup is displayed, I think):

The same method should work for any DialogGUI* based mod. I'm planning to use a close variant of that code soon, so if it looks crazy to anyone, please say so.

Link to comment
Share on other sites

On 10/16/2016 at 0:09 PM, DMagic said:

 


			RectTransform resultRect = resultsDialog.GetComponent<RectTransform>();
			Rect pos = new Rect(0.5f, 0.5f, 300, 300);
			if (resultRect != null)
			{
				Vector2 resultPos = resultRect.position;
				float scale = GameSettings.UI_SCALE;

				int width = Screen.width;
				int height = Screen.height;
				float xpos = (resultPos.x / scale) + width / 2;
				float ypos = (resultPos.y / scale) + height / 2;
				float yNorm = ypos / height;
				pos.y = yNorm;
				pos.x = xpos > (width - (550 * scale)) ? (xpos - 360) / width : (xpos + 360) / width;
			}

 

Does this part still work as intended with UI scaling? I'm seeing some strange behavior trying to save and restore window position when GameSettings.UI_SCALE is anything other than 1.0. At 100% scale, the X and Y coords are each in [0,1] with (0.5,0.5) at the center of the screen; but at 150% the (0.5,0.5) point is shifted way down from the center, and at 80% it's maybe 200px upwards on my screen. The net effect is that if I use the above calculation, it works perfectly at 100%, but my window shifts upward at <100% scales and downward at >100% scales. Strangely, the X coordinate works just fine.

Has anyone found a consistent pattern to these changes? Are the visible ranges exposed on a stock object somewhere? I'm in a very trial-and-error mode trying to investigate this at the moment, but I know there must be some deeper logic eluding me.

Link to comment
Share on other sites

@HebaruSan It's still working for me, the same code puts the window where it should be every time, right next to the experiment results dialog. That starts out getting its position from what the experiment results dialog says though, so I'm not really sure what the actual value for the y position is.

It's not surprising that positioning could be a problem though. For a truly baffling example look at Contracts Window +, which I think because it uses a nested Canvas has all sorts of weirdness going on. :confused:

Link to comment
Share on other sites

1 hour ago, DMagic said:

For a truly baffling example look at Contracts Window +

Thanks, that link gave me an idea for my own hack workaround for this.

(Set the position, check what it actually turns out to be according to my saving formula, then calculate the offset and set the position again before we forget what it was supposed to be. That way it's independent of the specific UI_SCALE, and might even survive future changes or fixes to the MultiOptionDialog stock code.)

Link to comment
Share on other sites

What do I need to do to get a DialogGUITextInput to soak keypresses instead of passing them through?  I've got PopupDialog.SpawnPopupDialog configured with isModal = true, but the keypresses for the text input pass through (which does fun things when it's the spacebar during flight).

Link to comment
Share on other sites

37 minutes ago, MOARdV said:

What do I need to do to get a DialogGUITextInput to soak keypresses instead of passing them through?  I've got PopupDialog.SpawnPopupDialog configured with isModal = true, but the keypresses for the text input pass through (which does fun things when it's the spacebar during flight).

Grab an input lock for the duration that your textinput is focused.

 

Link to comment
Share on other sites

  • 5 weeks later...

man been trip trying to rewrite MCE with this newGui.  Most of this thread has helped a huge amount, but I have not been able to find a good example on how to use

DialogGUITextInput()

So I understand most of it other than what should I use for 

<fuc> string,string 

part.

so getting the text input to change user input string and save it to another part.. The save part is all set.  OnGui version seemed more straight foward.. :) Like below is using the old methods.

GUILayout.Space(5);
                GUILayout.BeginHorizontal();
                GUILayout.Box("Contract Name", MCE_ScenarioStartup.StyleBold, GUILayout.Width(150), GUILayout.Height(30));
                SaveInfo.ComSatContractName = GUILayout.TextField(SaveInfo.ComSatContractName, 50);
                GUILayout.EndHorizontal();

 

Edited by malkuth
Link to comment
Share on other sites

4 minutes ago, malkuth said:

what should I use for 


<fuc> string,string 

part.

That's a function that accepts a string as a parameter and returns a string. I believe it tells you the current value of the field when it changes via the parameter, and allows you to make changes via the return value. I used it briefly in the older revisions of this file (but just to capture the value, not change it):

Link to comment
Share on other sites

20 minutes ago, HebaruSan said:

That's a function that accepts a string as a parameter and returns a string. I believe it tells you the current value of the field when it changes via the parameter, and allows you to make changes via the return value. I used it briefly in the older revisions of this file (but just to capture the value, not change it):

Thanks HerbaruSan.  That does work.. And it saves also as long as the String your grabing is persistant.. Which in my case it already was from the old method.  

Link to comment
Share on other sites

9 minutes ago, RockyTV said:

Is it possible to update a string in a dialog that was already spawned?

Yes; look for constructors where the label string is replaced with a Func<string> :

DialogGUILabel (Func< string > getString, float width, float height=0f)

You can pass a function that returns the string to use, and Unity will call that function every tick when it draws the window.

Link to comment
Share on other sites

  • 3 months later...

Anyone know how to add an OnFocus event/callback onto DialogGUITextInput so I can set InputLockManager? you can probably guess what pressing space does >.<

I'm having a hard time figuring it out, never used events with Unity before and couldn't make sense of how ScanSat was taking care of the issue.

I don't want to Lock input for the whole Popup, just the Text input.

Any help would be appreciated. :wink:

Link to comment
Share on other sites

@PiezPiedPy SCANsat is using a rather clunky method of handling input fields, and I'm not exactly sure why (it uses its own on select event then monitors the status of the input field's isFocused value to handle deselection), there are simple TMP_InputField events that should work fine for the purpose.

The TMP_InputField.onSelect and onDeselect events do exactly what they sound like, fire an event whenever the input field is focused on or when the focus is removed (at least I'm pretty sure that's what they do, online documentation for TMP is strangely non-existent).

For the DialogGUITextInput class it's a little tricky, since the TMP_InputField isn't actually generated until the dialog is created. So what you would need to do is make the DialogGUITextInput, keep a reference to it, then generate the DialogGUI, then once the dialog is spawned access its uiItem field, get the TMP script, then attach the events.

So:

DialogGUITextInput input = new DialogGUITextInput(...);

...

PopupDialog.SpawnPopupDialog(... input goes somewhere in the MultiOptionDialog...);

TMP_InputField tmp_input = input.uiItem.GetComponent<TMP_InputField>();
  
tmp_input.onSelect.AddListener(new UnityAction<string>(select listener method));
  
tmp_input.onDeselect.AddListener(new UnityAction<string>(deselect listener method));

Inside the listener methods is where you would set KSP's input locks. The string passed through the events are just the text in the input field and shouldn't matter for this purpose.

Squad could easily add listener callbacks to the DialogGUITextInput class constructors, but for now you have to do something silly like this to handle input locks. :mad:

Link to comment
Share on other sites

@DMagicThanks for that, worked perfect. :D

Also anyone else wanting to use DialogGUITextInput be aware that if you don't specify the placeholder text then KSP will fill in the field for you with the input text instead of leaving it blank, which is a bit annoying as when you delete the text at runtime in the game it will reappear in the text box as the placeholder and might confuse users. As a workaround if you don't want to use the placeholder then use a space instead of leaving it out.

e.g. Use:

manual_target_textinput = new DialogGUITextInput(manual_target_txt, " ", false, 35, OnTextInput_TargetManual, 23);

Instead of:

manual_target_textinput = new DialogGUITextInput(manual_target_txt, false, 35, OnTextInput_TargetManual, 23);

 

Link to comment
Share on other sites

  • 11 months later...

I should consider this topic "official" discussion for DialogGUI, though i did separate posts and i'm willing to change to this topic only to keep all related problems and solutions in one spot (even though this is offically "necroposting").

So, i've got the problem with DialogGUIBox. I think this element is used for grouping other basic UI elements such as labels, buttons, sliders etc...

Assuming above is correct, i can't properly set positions of UI elements inside box. When i add two labels, they appear waaay in upper left corner, far outside popupdialog window, and label text is vertically aligned.

I tried placing box inside horizontal layout, tried to add content sizer as first element... nothing helps.

So, does anyone have a working example of using box as container for other elements (again, if that is a proper use of box) ? Maybe a dumbed-down-hello-world style example ?

Link to comment
Share on other sites

6 hours ago, fatcargo said:

So, i've got the problem with DialogGUIBox. I think this element is used for grouping other basic UI elements such as labels, buttons, sliders etc...

I did all of my layout with DialogGUIHorizontalLayout and DialogGUIVerticalLayout, nested as needed. I don't think that's what DialogGUIBox is meant to be used for, but I can't prove that because the documentation doesn't really explain it.

Link to comment
Share on other sites

Thanks ! I suspected this might be the case, which leaves DialogGUIBox() in questionable usability - if used on it's own, its functionality could have been duplicated with label with no text for example.

Then again, it could be similar to DialogGUISpace(), just with added box for visibility.

It is odd that it accepts any UI elements at all :) .

Link to comment
Share on other sites

A quick google shows the MIssionController2 plugin using DialogGuiBox(), but seems to only use it for basic stuff. https://github.com/malkuth1974/MissionController2/search?q=DialogGuiBox&amp;unscoped_q=DialogGuiBox

Have you tried putting your labels inside a VerticalLayout, and then adding that to the DialogGuiBox?

Link to comment
Share on other sites

Originally, while i was learning about UI there were two competing approaches with KSP Assets and DialogGUI.

First i tried creating an asset as per instructions but have given up, then i tried DialogGUI which worked.

My confusion arised when i thought that panel object used in UI design inside unity editor had an equivalent method in C# and i mistakenly associated it to DialogGUIBox. I was wrong.

Anyway, i've got all i need from various coding experiments and have continued development.

Link to comment
Share on other sites

On 10/27/2018 at 1:18 AM, fatcargo said:

Originally, while i was learning about UI there were two competing approaches with KSP Assets and DialogGUI.

First i tried creating an asset as per instructions but have given up, then i tried DialogGUI which worked.

My confusion arised when i thought that panel object used in UI design inside unity editor had an equivalent method in C# and i mistakenly associated it to DialogGUIBox. I was wrong.

Anyway, i've got all i need from various coding experiments and have continued development.

Look at my code here: https://github.com/jarosm/KSP-BonVoyage/tree/devel/BonVoyage/gui

Specifically SettingsWindowView is using DialogGUIBox and result is this:

J7ZrxnNm.png

 

I'm coding it and experimenting right now, so don't hesitate to ask, if you have any questions.

For example, I needed to change a color of a status text on the fly. So I hooked the change to an event and when status changes, then I refresh the inner list of vessel. One hour of testing of different approaches, but in the end refreshing the whole list is the easist and the quiickest way.

Link to comment
Share on other sites

On 11/1/2018 at 8:17 PM, fatcargo said:

I was away for several days. I searched at github for "SettingsWindowView" and " DialogGUIBox", neither has been found.

It's in the devel branch. Click on the link above or switch branches in code section.

Or look here: https://github.com/jarosm/KSP-BonVoyage/blob/master/BonVoyage/gui/SettingsWindowView.cs

Edited by maja
Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...