Jump to content

Need help building a simple interactive GUI


Recommended Posts

There isn't a whole lot of relevant, or recent info on how to make GUIs that I've been able to find. There aren't any descriptions in the API, and it sounds like there are also several different ways to create GUIs in the game, which is only adding to my confusion.

I tried watching the Cybutek videos on Youtube, but all he does is build a window with no interactivity, so the videos aren't really all that helpful (the videos are also from KSP v0.19, so I don't know how much, if any of it, is still applicable).

I'd like to have a single GUI in the ship editor, where at the top is a main label and a corresponding text box where the user can input something. Below that will be a list of every part on the vessel that has crew capacity more than 0, and a corresponding text field for each. Finally, when submitted, I need the value in the main text field at the top to be stored in the .craft file where the vessel name and description values are stored—and the inputted values for the crew-capable parts will be stored in their respective nodes in the .craft file.

I'm assuming I'm going to need to do some sort of part list search in order to populate the GUI. Since this plugin is only going to be added to crew-able parts, I just need to search for the parts on the craft that have the module. I don't imagine that will be all that difficult to figure out how to do, but what I don't currently have a clue about is how I'd be able to individually list all those parts in the GUI.

As far as user input, looking through the API for GUIUtil, I found this, which looks promising:

public static	string	EditableTextArea(string caption, string value, Callback<string> onSubmit, GUILayoutOption[] guiOptions)

But I'm having a difficult time figuring out what the individual parts do. Firstly, I can't tell if this only creates a text field, or if it creates an entire window with a text field in it. I'm also unsure of the string caption, and string value. Is the caption what shows up in the text field, sort of like how "Untitled Spacecraft" shows up in the Vessel name text field, or will it be a label on the side of the text field?

It kind of looks like "string EditableTextArea()" is a string, whose value is declared by Callback<>?

Or maybe I'm on the completely wrong path and should be looking for something else altogether?

One last question, when doing preliminary research on the creation and layout of .craft files, I found that .craft files aren't created until after they're saved, not when you actually start a new craft. My question is how and where is the .craft file written before it is saved and accessible in the ships folder? I'm concerned that I won't have an easy way to access those values until after the ship is saved. It's a minor concern, since people probably save their crafts pretty quickly after creating them, but I'd still like to know if I'll have to include some disclaimer telling users to save their craft before they can use my plugin.

Sorry for such a long post. As always, any and all input is greatly appreciated!

Link to comment
Share on other sites

Warning, I'm not an expert in this but below is based on some of my findings from experimenting with KSP mods.

Simple example of an editor window using "old" immediate mode UI (omits the code you'd need to add to wire it up to an app launcher button in the editor):

public class Editor {

	Data data;
	int windowId = 12345555789; // some random unique number

	public void Draw(Data myData) {
		data = myData;
		var position = new Rect(0.5f * Screen.width - 200.0f, 0.5f * Screen.height - 250.0f, 400.0f, 500.0f); // location and size of editor window
		position = GUI.Window(windowId, position, OnWindowGUI, "Window title", HighLogic.Skin.window);
	}

	void OnWindowGUI(int id) {
		GUILayout.BeginVertical();

		// main text box row
		GUILayout.BeginHorizontal();
        GUILayout.Label("Main title"); // label for row
        GUILayout.Space(20);
		data.MainText = GUILayout.TextField(data.MainText, GUILayout.Width(200); // show current value in text box and store it back into data when changed.
		GUILayout.EndHorizontal();

		GUILayout.Space(10); // padding between rows

		// create other rows in loop

		
		if (GUILayout.Button("Save", GUILayout.Width(100.0f)))
		{
			// save values of data to permanent locations.
		}

		GUILayout.EndVertical();
	}
}

If you've created a custom part module and used a Module Manager config to add it to all crewed parts then you can get a list something like:

var parts = EditorLogic.fetch.ship.parts.Where(p => p.CrewCapacity > );
foreach (var p in parts)
{
	var myMod = p.FindModuleImplementing<MyModule>();
	if (myMod != null)
	{
		data.ModuleParts.Add(myMod);
	}
}

Provided your module has a persistent field for the value(s) you want to set then any value you save to that field will be saved to the craft file when it is created.

I believe you can access the ship name and description through:

EditorLogic.fetch.shipDescriptionField.text = "Some description";
EditorLogic.fetch.shipNameField.text = "Some name";

 

Link to comment
Share on other sites

2 hours ago, Aelfhe1m said:

If you've created a custom part module and used a Module Manager config to add it to all crewed parts then you can get a list something like:


var parts = EditorLogic.fetch.ship.parts.Where(p => p.CrewCapacity > );
foreach (var p in parts)
{
	var myMod = p.FindModuleImplementing<MyModule>();
	if (myMod != null)
	{
		data.ModuleParts.Add(myMod);
	}
}

Provided your module has a persistent field for the value(s) you want to set then any value you save to that field will be saved to the craft file when it is created.

I believe you can access the ship name and description through:


EditorLogic.fetch.shipDescriptionField.text = "Some description";
EditorLogic.fetch.shipNameField.text = "Some name";

 

Firstly, I appreciate you taking the time to reply, and providing code to study, too.

I'm only vaguely understanding a lot of what you mention in your post, so I think I'll need to look a little more closely at it tomorrow. But for now, what about simply editing nodes of a particular type instead of searching? I was looking through the API and found configNode, and it looks like I might be able to add values to a node directly from user input using

public	Void	AddValue(string name, string value)

Where string name can be declared right then and there, and string value can be declared using the user input in the GUI. Would this be a viable alternate method, or am I fundamentally misunderstanding your reply?

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...