Jump to content

A GUI framework for modders?


Recommended Posts

So I have been tinkering with KSP coding for a while now, contributing where I can, but as a newcomer to unity and c# in general, I am finding that UI coding is fraught with some annoying pitfalls. Simply having a window that behaves as one expects (Remember position, close when ship change etc) and with the niceties that a windows generation has grown accustom to is not trivial.

I have a lot of these sorted in my mod, but to be honest the code probably isn't that great, and only supports per-mod not per-ship settings etc.

Taranis (Tac) was kind enough to release a window manager library that hopefully will be the first step to a decent solution.

Unfortunately, he did not include a fully working sample, so I am currently wrestling with that. Rather than just integrate his code into my mod though, I thought it would be nice to feed something back and try to create a nice framework with a sample "Hello World" implementation to allow budding modders to dive right in with a fully working UI they just have to modify to suit their needs.

So, any opinions on the best way to implement such an idea? At a minimum, I think the framework should provide the following functionality:

  • Remember window position
  • As you [] through ships, the window shows and hides as appropriate
  • A basic example UI logic and storing of state variables
  • An open/close option in the part's context menu with code to toggle label

I would also like to see:

  • Two levels of persistent data storage: global and per-ship
  • A "Show on Start" option

To that end, I would encourage anyone to fork either Tac's original library or my fork and add or suggest any improvements or fixes they deem suitable.

One question that crossed my mind also was how this would apply to part-less mods. Could one example be made that would work in both situations, or would it require two?

Link to comment
Share on other sites

This kind of library approach would be totally awesome. The only true stopper would be that the original author would go pretty much unnoticed by the general playerbase, which is probably why its never been completed.

Us modders would have to think of a way to make sure that any potential library authors would get a large credit.

I would like to add, not only would a GUI window library be handy, but, also a file saving library would also be of much use.

If this gets done, I will be adding rep to this thread :D

Link to comment
Share on other sites

Personally, am not hugely concerned about the glory, I just think it's worth trying to do.

Besides, if for example we use Taranis' code and host on GitHub, the relevant people get credit that way. Finally, I would imagine comments could get put in the source to credit contributors.

What do you mean by "file saving"? Does it need to be files or could it not just be a node in the XML or something?

Whatever, I think you have a valid idea: flesh out storage options available to modders from within the code.

I also thought that a premade block for all the events with comments and when they fire would be nice, or at least a list of the main ones.

Check out my fork for the beginnings of a usable template.

Window position now saved on a global basis.

Link to comment
Share on other sites

I am Taranis Elsu, and I endorse this project.

Seriously though, I was thinking of working on an example library to help share the knowledge. Some of the discussions and questions on #kspmodders leads me to believe that it would be really helpful to the community. We could stop reinventing the wheel with each new mod, we could have more consistency between mods, and beginners would have a good starting point.

My initial focus would be on the simple things that nearly every mod does: showing a window and saving settings. evilC has done a nice job getting the ball rolling, and I plan to help him. More help would be appreciated :)

Link to comment
Share on other sites

Absolutely delighted to have Taranis on board, he dropped into IRC a while ago and gave me a few pointers, so I have modified the code to remove reliance on PluginConfiguration nodes (ie config.xml in Resources) and instead use ConfigNodes (eg a .cfg file in the plugin folder).

This seemed to be the consensus as "the smart way" in #kspmodders, and an excellent example of why I feel this project holds value.

The latest version also supports a "global" setting in the .cfg file, which can be overridden by a "per-ship" setting saved in the persistence file.

Link to comment
Share on other sites

Have you played with other UI frameworks? One of the biggest annoyances with Unity is that it's not declarative. (It's a procedural UI... yuck!) I don't have trouble with it myself, but if you're looking to make a UI framework, make sure you're familiar with frameworks like WPF. Even a primitive form of data binding could go a long way.

Link to comment
Share on other sites

Hmm, as a first step I was just looking to package what KSP offers into a more manageable starting point for newcomers.

I agree the UI is a bit quirky, but given a simple example, it should be easy enough to pick up. Personally, something like a proper framework is way beyond me.

Link to comment
Share on other sites

I agree that a proper framework is too much. My thoughts are to create some classes that factor out some of the code that is duplicated every time you want to show a window, have the window remember its last position, and properly handle window hiding when paused or in screenshot mode. That was the intention of my TacLib, but for personal use.

I think it is also useful for showing others how to do some of those common things that we all do.

I also do not like Unity's GUI. I would much prefer something like WPF or Swing or something -- just not MFC!

Link to comment
Share on other sites

Starting to get somewhere with this.

New version up, "Show on Startup" option added, context menu toggle added to part to show/hide window.

Taranis - do you know how to solve issue #2?

Link to comment
Share on other sites

  • 2 weeks later...

I have made an important bugfix to the library.

At some point (probably after sirkut grabbed it), I broke it such that trying to add or load a part with the partmodule whilst in the Editor would hang KSP.

The window is also now passed the whole partmodule instance, so it can access info about the associated craft.

I also updated the sample module so that it lists all available resources as a demonstration of the above feature, and puts it in a toggleable scroller, as a demonstration of UI techniques.

Link to comment
Share on other sites

Stupid newbie here, with a stupid newbie question. Please have pity on me.

I'm trying to compile this with the version of MonoDevelop that came with Unity3D, using Assembly-CSharp.dll and UnityEngine.dll from KSP 0.20. I'm getting about five compile errors, all seem to be related.

Example: file Windows.cs, line 67

var texture = Utilities.LoadImage<T>(IOUtils.GetFilePathFor(typeof(T), "resize.png"));

error No overload for method 'GetFilePathFor' takes 2 arguments.

Using contextual help it appears to be expecting GetFilePathFor(Type T, string file, Vessel flight);

which means the "flight" parameter is missing.

What am I doing wrong?

Link to comment
Share on other sites

Hmm, you may well not be doing anything wrong - that bit of code isn't really needed anyway, it just allows you to assign a texture to the resize button.

I commented out those two lines and replaced it with


resizeContent = new GUIContent("R", "Drag to resize the window.");

Does that compile for you?

Link to comment
Share on other sites

Hmm, you may well not be doing anything wrong - that bit of code isn't really needed anyway, it just allows you to assign a texture to the resize button.

I commented out those two lines and replaced it with


resizeContent = new GUIContent("R", "Drag to resize the window.");

Does that compile for you?

Yes it does, thank you!

Link to comment
Share on other sites

So I take it that Visual Studio does not do a check on API function arguments when it does a compile, unlike MonoDevelop?

Just for the record, MonoDevelop complained about the following lines:

Windows.cs, line 67: var texture = Utilities.LoadImage<T>(IOUtils.GetFilePathFor(typeof(T), "resize.png")); No overload for method GetFilePathFor takes 2 arguments

Windows.cs, line 197: windowPos = Utilities.EnsureVisible(windowPos); No overload for method EnsureVisible takes 1 argument

Icon.cs, line 54: var texture = Utilities.LoadImage<T>(IOUtils.GetFilePathFor(typeof(T), imageFilename)); No overload for method GetFilePathFor takes 2 arguments

Utilities.cs, line 95: if (File.Exists<T>(filename)) No overload for method Exists takes 1 argument

Utilities.cs, line 97: var bytes = File.ReadAllBytes<T>(filename); No overload for method for ReadAllBytes takes 1 argument

I must be doing something wrong, MechJeb calls IOUtils.GetFilePathFor() with two arguments, just like your code does. Offhand I'd say that MonoDevelop is being overly fussy about default parameters, meaning it is not allowing any.

I'll figure it out.

Edited by nyrath
Link to comment
Share on other sites

OK, I found the problem.

In MonoDevelop, when I imported the files, the project set itself to .Net version 3.5.

When I set the project to .Net version 4.0, everything compiled just fine.

Link to comment
Share on other sites

FYI: Plugins should target .NET Framework 3.5. I recommend reworking that code instead of changing the target framework.

I've wondered about this. I've seen some plugins where users compiled for 4.0 framework and they work just fine. What problems can be encountered if not using 3.5?

Link to comment
Share on other sites

I think i goofed anyway.

It seems there is an icon.cs in there, but it is not part of the solution.

Also, there is a resize.psd, but it looks like the code should be able to hold a missing icon.

I saw taranis made some changes in that area, I may need to merge them in.

When I find a bit of time i will have a look at it.

Link to comment
Share on other sites

Hmm, OK, the TacLib project was set to 4.5

[Edit] When I changed project to 3.5, I had to remove the reference to Microsoft-CSharp and comment out the line "using System.Threading.Tasks"

The project compiled after I did that, so I guess all is good.

I submitted changes to GitHub

Edited by evilC
Link to comment
Share on other sites

I've wondered about this. I've seen some plugins where users compiled for 4.0 framework and they work just fine. What problems can be encountered if not using 3.5?

You'll usually only encounter problems if you make use of classes or members introduced in 4.0 or later. This leads a lot of people to believe they can write plugins targeting 4.0 or higher when that's not at all reliable.

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