#Make a mod with a UITK GUI

1 messages · Page 2 of 1

dusty berry
#

unfortunatelly this process is a bit repetitive, but its the best we can do shrug

marble shale
#

It's not bad, and it's very clean and organized

dusty berry
#

The biggest "learning curve" to them is lambdas and how to use them properly

#

if you don use lambdas you'll end up with 1 method per textfield xD

marble shale
#

Is that what we're doing? Using lambdas?

dusty berry
#

yes, when you do something like
() => WhatYouWantToDoHere

#

you're doing a lamda expression

#

the way it works is
Arguments of the method => body of the method

#

its a short way do create a method (tho you have no way to reference these lamda expressions)

#

so they are mostly used for methods that will only be used by 1 thing

marble shale
#

    _container.Q<Button>("LargeTimeDecreaseButton").clicked += () => IncrementTime(-largeStepTime);
    _container.Q<Button>("SmallTimeDecreaseButton").clicked += () => IncrementTime(-smallStepTime);
    _container.Q<Button>("SmallTimeIncreaseButton").clicked += () => IncrementTime(smallStepTime);
    _container.Q<Button>("LargeTimeIncreaseButton").clicked += () => IncrementTime(largeStepTime);

    _container.Q<Button>("DecreaseOrbitButton").clicked += () => IncrementOrbit(-1);
    _container.Q<Button>("IncreaseOrbitButton").clicked += () => IncrementOrbit(1);```
#

Did the same for orbits and time

dusty berry
#
Action<string, int, float> lamba = (name, age, height) => Debug.Log($"Person:{name}\nAge:{age}\nHeight:{height}m");
//its the same as
void DebugPerson(string name, int age, float height)
{
  Debug.Log($"Person:{name}\nAge:{age}\nHeight:{height}m");
}
//and you can use just (name, age, height) => Debug.Log($"Person:{name}\nAge:{age}\nHeight:{height}m") wheverever you want
marble shale
#

I've seen them used in the optimization solvers in the old MechJeb code. I never did understand them. I should take some time to.

#

But, in the meantime, another question!

dusty berry
#

they are so good! but they can be very overwhelming

#

Go for it!

marble shale
#

So some of these GUI things should only be shown situationally. For example the SnapTo for ANt and DNt are only shown if you have a taget and it's orbiting the same reference body you are.

#

Where can I check that and set the visibility/accessibility of the UI elements?

dusty berry
#

easy, VisualElement.style.display = DisplayStyle.None;

#

but take into consideration that this will also make it not be calculated to the elements positions

#

what does this mean

marble shale
#

Those are at the end of the list

#

If they come and go together and nothing follows them on that row

dusty berry
#

both labels are on the edges, if i make the display none for the middle visual element

dusty berry
#

but its a good thing to take into consideration when doing these things, if you dont wish for this to happen you can use VisualElement.style.Visibility = Visibility.Hidden

marble shale
#

I'm guess ing this next bit might go in Update?

dusty berry
#

also dont forget to set them back on when the right ocasion comes!

marble shale
#

I'm thinking like IMGUI, aren't I>

dusty berry
marble shale
#

?

dusty berry
#

no you deffinetly could do it on update

#

its just more performant to not do it

#

but depending on what you do wont have an noticeable impact on the game

marble shale
#

It might be tricky with the game's event messages. I could check any time the target changes, but what if you're outside the Mun's SOI headed to the Mun, and some satellite is your target. Maybe your target doesn't change but your reference body changes...Hmmm....

#

So maybe check any time either changes...

#

Then the only gotcha is if the other thing is coming to you, which is not likely untilwe've got MP

dusty berry
#

the body reference only changes on SOI change

#

(i think)

marble shale
#

Yeah, so I would want to subscribe to reference body change and target change, and in either case test to see if the targe is at the same reference body

dusty berry
#

but either way, if you feel like the game's message wont do justice go for the Update! the game's messages are a bit buggy sometimes so might be more consistent

#

its trully up to you!

#

only thing you have to take into consideration is not doing too many expensive things on update

marble shale
#

I think I'll go wtih Update for now as it's brute force and going to work, then explore the event solution as being more elegant

dusty berry
#

sounds good!

marble shale
#

Always try brute force first, that way if you mess it up you've broken it.

#

Oh,,, wait...

#

Don't do that in the kitchen...

#

or the lab...

dusty berry
#

xD or do it! thats how u discover new flavors or explosions, or explosions of flavors

marble shale
#

LOL

#

sounds good, I've scetechd out this

#

// Test if there is a target
// test if the target is at the same reference body as the active vessel
// If both are true, then _container.Q<Button>("SnapToANtButton").style.display = DisplayStyle.None

dusty berry
#

oh dont

#

remember

#

Q<> is a query

#

and queries are expensive

#

its better to store the button as variable if you're gonna do things to it more than once

#

Button SnapToANtButton;

#

but yeah the logic behind it is right!

marble shale
#

OK, how do I set the button variable to point to the button?

dusty berry
#

btw we're okay with doing Q<> on the InitializeElements because we're only doing it once

dusty berry
#

the difference is that you weren't saving the variable after, you were using it right away

#

oh btw, UITK has a way to make an element disabled but not hide it

#

looks something like this

#

most of the times is prettier to just hide it, but maybe you're looking for something like this MisatoPray

#

btw the difference between saving the Button/TextField/Label or whatnot and using it right away is minimal, will most just save a couple kb (or mb depending on the class size) of RAM

#

but i like to always propagate good code practices, thats why i told you to do it that way

marble shale
#

Yeah, for my purposes in this case I'd like to hide it entirely rather than graying it out

dusty berry
#

MisatoPray then do the DisplayStyle.None

marble shale
#

Hey I'm getting an issue with this

  private void CenterWindow(GeometryChangedEvent evt)
  {
    var root = _container.hierarchy[0];
    root.transform.position = new Vector3(
        (Screen.width - root.boundingBox.width) / 2,
        (Screen.height - root.boundingBox.height) / 2);
    _container.style.visibility = Visibility.Visible;
    _container.UnregisterCallback<GeometryChangedEvent>(CenterWindow);
  }```
#

It says there is no boundingBox

dusty berry
#

well thats wierd

marble shale
#

theres localBound

dusty berry
#

tho its an easy fix

marble shale
#

and worldbound

dusty berry
#

i didnt realize this earlier but munix made an helper method for that

#

can you send me a print of where ur calling CenterWindow?

marble shale
#
  public void SetupDocument()
  {
    var document = GetComponent<UIDocument>();
    if (document.TryGetComponent<DocumentLocalization>(out var localization))
    {
      localization.Localize();
    }
    else
    {
      document.EnableLocalization();
    }

    _container = document.rootVisualElement;
    _container.style.visibility = Visibility.Hidden;
    _container.RegisterCallback<GeometryChangedEvent>(CenterWindow);

    SnapToANtButton = _container.Q<Button>("SnapToANtButton");
    SnapToDNtButton = _container.Q<Button>("SnapToDNtButton");
  }```
#

once here

#

and once also here

#
  private void CenterWindow(GeometryChangedEvent evt)
  {
    var root = _container.hierarchy[0];
    root.transform.position = new Vector3(
        (Screen.width - root.boundingBox.width) / 2,
        (Screen.height - root.boundingBox.height) / 2);
    _container.style.visibility = Visibility.Visible;
    _container.UnregisterCallback<GeometryChangedEvent>(CenterWindow);
  }```
#

It seems like it's recursive?

#

CenterWindow calls CenterWindow?

dusty berry
#

on the 2dn one u are Unregistering it

marble shale
#

OIC

dusty berry
#

basically you're saying, call this, and once you call it, never call it again

#

tho you can delete the CenterWindow method (all of it)

marble shale
#

done

dusty berry
#

and replace


    _container = document.rootVisualElement;
    _container.style.visibility = Visibility.Hidden;
    _container.RegisterCallback<GeometryChangedEvent>(CenterWindow);

with

    _container = document.rootVisualElement;
    _container[0].CenterByDefault();
    _container.style.display = DisplayStyle.None;
#

just edited it btw!

marble shale
#

Got it

#

BTW, my SetEnabled is needing some work

dusty berry
#

talk to me!

marble shale
#

I dropped in what I have from the Toggle method I had fore IMGUI.

#
  private void SetEnabled(bool newState)
  {
    interfaceEnabled = toggle;
    GameObject.Find(ToolbarFlightButtonID)?.GetComponent<UIValue_WriteBool_Toggle>()?.SetValue(interfaceEnabled);
  }```
dusty berry
#

can you show me how its looking?

marble shale
#

So, wrong

dusty berry
#

easy fix!

marble shale
dusty berry
#

you just hid your Window with this on the code that you just made
_container.style.display = DisplayStyle.None;

#

so just

_container.style.display = DisplayStyle.Flex;

marble shale
#

Yep

dusty berry
#

tho you'll need to do some "conversion"

#

so maybe put a if(newState) DisplayStyle.Flex
else
DisplayStyle.None

#

also you probably dont need interfaceEnabled, but some people (munix ie) like to have a variable that you can access to know if your ui is open

marble shale
#
    if (newState) _container.style.display = DisplayStyle.Flex;
    else _container.style.display = DisplayStyle.None;```
dusty berry
#

exactly!

#

wait a sec

#

no yeah thats right

marble shale
#

I thik I only ever used that variable in the OnGui part of the mod. I could check easily enough

dusty berry
#

most probably yeah, but again if you want to keep it feel free to!
bool variable only ocuppy 1 byte of RAM (each) so those are your smallest (literally) problems

#

on the other hand, saving IE a Button (visual element) probably take 10kb (or more) each since they have a LOT of variables inside them

marble shale
#

They occupie 1 whole byte? That's 7/8ths waisted space!

dusty berry
#

xD i'm probably wrong on that tbh, gotta get my variable-to-size knowledge checked

marble shale
#

So, I still need to learn how to set the values for things.

dusty berry
#

oh seems like it is one byte!

dusty berry
marble shale
#

Those should be updated frequently in some cases, and only when things change in others

#

Yes, the labels I'm using to dispaly values

dusty berry
#

those are easy tho

#

but Label i do recommend saving as a variable

#

since you'll access them a lot

#

Basically its as easy as it can get

marble shale
#

That makes sense.

dusty berry
#

Label.text = "Text";

marble shale
#

OK, that will be easy

#

to declare the variables what is the type?

dusty berry
#

Label!

#

the same Control/Container name that you have on the UIBuilder corresponds to the class (99% of the time)

marble shale
#

This is funny, vs thinks these varaibales can be removed since nothing ever reads them

dusty berry
#

yet xD

marble shale
dusty berry
#

well maybe you're not using them no?

#

do a RightClick>Find All References

#

or Shift+F12 if your text-bar-thingie is on them

#

if you are using them there then just disregard vs being dummy

marble shale
#

Oh yeah, that code is commented out

dusty berry
#

that helps

marble shale
#

That's only until I track down what I need to test before setting them

dusty berry
#

sounds good!

#

btw, for now, for the "select Maneuver node 0 of 1" do it the normal way

#

in a couple of days i'll release the custom controls

marble shale
#

Sure, that's easy.

dusty berry
#

it will be the easiest change you'll ever do! tho i'd rather that you have them in the right way (via Uitk For KSP2) than having to change it later

marble shale
#

I'm thinking that initially for the labels I'll just set them all in Update. I can clean that up later if I like, but that will work

dusty berry
#

sure, it works!

marble shale
#

So I'll set them to their respective labels in SetupDocument, then set their values in Update

dusty berry
#

InitializeElements()* but yes!

#

after this you're ready to test it in game!

marble shale
#

I'm thinking right now this mod has both GUI's in it, or all of one and part of the new one with some stub functions

dusty berry
#

xD i mean you did port most of the IMGUI code into it

marble shale
#

LOL! It works! sort of...

dusty berry
#

what parts dont work?

marble shale
#

Look! Two copies!

dusty berry
#

but im glad it does! sort of xD

marble shale
#

Which reminds me, there's the whole other mode it should go into when there are no nodes

dusty berry
#

you're probably instantiating it wrong then, when are you doing SetEnabled?

#

Oh

#

wait, you have 2, the other is IMGUI

#

makes sense

marble shale
#

And here they are with a node

#

Everything on the right is just dummy data of course

dusty berry
#

you can make the font smaller if you wish!

marble shale
#

I can see I may need to do some more work on the Unity gui, but it's coming along nicely

dusty berry
#

yeah, its coming along great!

#

much more readable with this font

#

also the colors are a lot more vivid

#

i would maybe make the Header font bigger tho

marble shale
#

I'm curious how I can pick a different font. When I tried in Unity it dodn't wnat to let me - I think maybe only only had the one loaded?

dusty berry
#

i think you can do it by makin an uss class targeting .unity-text-element

#

and setting the font there

marble shale
#

The text inputs look a bit screwy too.

dusty berry
#

yeah, thats the padding remember? or margin i trully cant remember

marble shale
#

Yeah, but I thoguht we fixed that

dusty berry
#

check in unity!

marble shale
#

Looks fixed in Unity

dusty berry
#

you migh need to repack the asset bundle then

marble shale
#

But screwy in the game

#

Maybe so, I'll do that when I mess some more with the fonts.

#

That said, the on hover and pressed buttons look nice

#

It works in several senses - I need to connect some stuff up and then make it a bit prettier with font changes, etc.

dusty berry
#

🙏

#

yeah i mean from now on you can do pretty much whatever you want on the uss

#

and your ui will work the same

marble shale
#

One question though. What about the mode where there are no nodes yet and all it should do is give you an option to make a node.

#

That's almost like tabs

dusty berry
#

thats easy

marble shale
#

really?

dusty berry
#

put everything that you want to be hidden on no nodes under the same visual element

#

and style.display = None

#

and then on the thing that you want to show
style.display = Flex

marble shale
#

OK, I get it

dusty berry
#

and then on code do that verification/apply these

#

tho we might need to tweak a couple things so that the window auto-resizes

marble shale
#

That makes sense for how it will work in the game. Laying it out in Unity Editor may look odd - like the whole GUI is way taller

dusty berry
#

yeah it does! its a bit odd indeed, but remember that you're working very zoomed in in the Unity Editor

#

its a common problem for UX/UI Designers, most of the times you are always very close to the ui and you dont see the bigger picture if you compare the 100% view on the uintyEditor with the game's it should be 1:1

marble shale
#

I'm not following quite yet. What I think this means (and I suspect I'm wrong) is that I have a visual element with some text and a button in it for no nodes, and then below that all the stuff I've got now that's below the blue line , and that's al captured in another element. Then in the game I can swap one on and the other off, but in the editor I'll see them both as if they're both one.

#

That's what I mean buy it looking taller in the editor

marble shale
#

Yes

dusty berry
#

the way you emulate that in the editor is by setting display to none (as you do in code)

marble shale
#

Oh!

dusty berry
#

the one that's marked as edited

#

everything that you access in code you can access here and viceversa!

#

Shadow ie built his whole windows only with code

marble shale
#

So it would be in the Hierarchy tree, but it only shows in the editor if I want to make it show

#

I've got it!

#

This makes sense and it will be easy

dusty berry
#

exactly! and you can also make the "default" state like that

marble shale
#

The only thing that will be longer is the hierarchy tree!

dusty berry
#

leave the default as displayed and the other as not displayed

#

Exactly xD

#

you'll use this same trick for the Tabs in FP

marble shale
#

I'm juessing I doe basically the same for FP with the tabs, except I have to figure out the dynamic buttons, but they'll be basically the same

dusty berry
#

but you'll need to make a TabController to make things easier for you (or not if you like to suffer)

#

yup xD

marble shale
#

I think I've got a tab controller now, but it would need to be refactored into this new approach.

#

But the logic is there

dusty berry
#

shouldnt be hard

#

see, FP wont also be that difficult

#

the most time consuming part is building the ui in the UI Builder

#

but thats a good thing because it allows you for a LOT of customization

marble shale
#

OK, cool. I'm gonna go play with this. I'm closer than I thought, but there's still quite a bit of work to do just migrating stuff over.

dusty berry
#

yeah, it would have been good to have UITK since the start to avoid migrating

marble shale
#

This is helping me immensely, btw!

#

Oh god yes!

dusty berry
#

we did have it in 0.4 but it wasn't nearly production ready

marble shale
#

I wish we'd had this at the start!

dusty berry
#

np! Im here to help! I want the best modding community possible

marble shale
#

I think we've got a pretty amazing one!

dusty berry
#

Indeed! hope it keeps like this as we grow

marble shale
#

You know what? The doomers that are so down on the game should try modding. It's a blast!

#

Seriously!

dusty berry
#

it is right? you literally do anything you want with the game

marble shale
#

This is how I play the game now!

dusty berry
#

xD this has been my KSP life for the last 2 and a half months

marble shale
#

heheh me too!

dusty berry
#

taking into consideration that the game launched 3 months ago...

marble shale
#

It's nuts!

dusty berry
#

also its very good to see people using our mods, cuz we do spend quite some time on them

marble shale
#

I remeber when it came out and I was just hoping somone would eventually start modding it...

#

I' was shocked how quickly mods appeared!

marble shale
#

hehehe yes!

#

but others first, they broke the ice

#

Once I reallized it was possible it was like Pandora's box was open

dusty berry
#

exactly thats what i love about coding

#

and modding as well

#

you can lquite literally turn the game inside out if you want

#

look at RSS RO ie, its almost a new game

marble shale
#

I've never done RSS RO. I probably should though

#

Engien question for you!

dusty berry
#

neither did i, i dont really like the "simulate real life" i like the arcady aspect of ksp

#

shoot!

marble shale
#

When these new extendable ones come out, can we mod them so that they have a degraded operating mode when not extended?

#

I want to be able to use them on landers for low grav like Mun and Minmus

dusty berry
#

yes im pretty sure we can

marble shale
#

I like the extended bell in space, but how can you land with that?

dusty berry
#

tho it will probably look very odd since the plume will be coming from its original position

#

but nothing that #1094320887228006450 can't fix

marble shale
#

That would be cool! I like articulating parts - they're fun to use

dusty berry
#

tho, putting a craft that wide in space is a bit difficult

marble shale
#

Side mount works OK, but I recall it being wobbly even in KSP1

dusty berry
#

not with one of my 150 mods (i just dont know which one did it xD)

marble shale
#

See, I always go to EPL as quick as I can, then I'm building them on Minmus

dusty berry
#

yeah same, tho lately i've been playing a more "accurate" way, so orbit, go to the mun, minmus create a space station

#

its a bit more challenging

#

which makes the game a more fun and makes you think more about your rockets than just re-do what you did for the last 10 saves

marble shale
#

I found that lugging stuff back up to orbit from Mun or Minmus was tedious. Maybe I did it wrong

#

But otherwise I love an orbital space dock!

dusty berry
#

well you can just wait on the surface of the moon, wait for your craft to be pointing Kerbin and full throttle xD

marble shale
#

Oh I was thinking put the station in Munar orbit

dusty berry
#

the deltaV to circularize on these small moons is almost not worth it (if you're trying to escape their SOI)

marble shale
#

You've have to land, collect resources and make more fuel, haul that back up to orbit, rinse and repeat until you had enough, then you could finally make somehting cool in orbit

dusty berry
#

orrr

#

you launch a Orange Tank with a probe core xD

#

launch it from kerbin, you'll wast only like 5% of it to get to the moon's orbit

#

tho i usually do this when i'm launching the "fuel tanks station module"

#

which reminds me that i hve to work on the colonization mod

marble shale
#

This makes me wanna play again, but I also want to see if I can get my mods out in UITK form before 0.1.3 hits

#

Yes! We need more parts!

#

I want to build colonies!

#

Everyone will want one!

dusty berry
#

same!
Tho fisrt i want to finish LFO Editor so anyone can change the game's plumes

marble shale
#

Or three!

#

Oh that will be so sweet!

dusty berry
#

1 per planet MisatoPray

marble shale
#

LOL! nice

#

Will the colored to match?

#

Red for Duna!

dusty berry
#

i mean waterfall is a BIG part of KSP1 modding, so nothing more fair than to focus on that first

marble shale
#

Green for Jool...

dusty berry
#

oh no xD you'll loose your colony like that

marble shale
#

Why, is the green radioactive?

dusty berry
#

tho it will be fun to see what people will do with the colors

#

Hwo will you see your colony on the Red Planet, with aRed colony?

#

xD

marble shale
#

Not a red colony, a red plume!

dusty berry
#

OH xD

marble shale
#

With your plume editor

dusty berry
#

well the game rn doesn't support that

#

but for sure i could do that

marble shale
#

Now I see why you thought I'd loose the colony!

#

LOL

dusty berry
#

xD

#

the goal for LFO

#

is to be able to add any effect to any GameObject in game

#

ie someone wanted to make geisers on IKe

marble shale
#

I'm gonna make me an Epstein Drive!

dusty berry
#

with the current LFO its pretty much possible, but we have no editor yet

#

Do whatever your imagination pleases!

#

i also have a shader ready that shows Tank frost when the tanks are full

marble shale
#

We'll get those or something like them eventually for interplanetary I suppose

#

That will be fun!

dusty berry
#

yes! Cvusmo is already making a particle accelerator engine iirc #1112981422836301844

marble shale
#

It's an engine? I thought it was antimater fuel production

#

I.e. a bomb

dusty berry
#

in not sure xD but he did mention making the plume a laser

marble shale
#

Did you ever read Project Hail Marry?

dusty berry
#

so i made the plume = engine connection

#

not really Sad_Chick

marble shale
#

Oh it's sooo good! Andy Weir - the guy who wrote The Martian

#

I think they optioned it as a movie too

dusty berry
#

ohh that one i know!

dusty berry
#

xD you can make that engine, i promise i'll read the book before you make it xD

#

saved!

marble shale
#

They're making a movie with Ryan Gosling apparently

dusty berry
#

oh thats cool i love ryan gosling

#

such a good actor

marble shale
#

Yes, he is!

dusty berry
#

BladeRunner is one of my fav movies!

marble shale
#

The new one?

dusty berry
#

yup that he's the lead actor

marble shale
#

It is good! I think they did a great job with that

dusty berry
#

yeah, i do like tho dissecate and analyze every movie that i watch and it was very nice to see their scenes

#

all are very grandious and using colors to drive your attention

marble shale
#

Yes! The attention to detail was amazing!

#

They captured such a dark and grity place so well

dusty berry
#

i love those dark movies tbh, nightcrawler, Sambojcow Room, Run all movies that i adore!

#

and all a very dark aesthetic

marble shale
#

Those are dark! I've not seen them, but Sambojcow Room sounds very dark!

dusty berry
#

well it translates to Suicide room xD

marble shale
#

Yes, I know! I googled it...

dusty berry
#

it won the Indie Movie of the year iirc

marble shale
#

I wouldn't have none otherwise, but yeah

dusty berry
#

basically talks about a teenaeer that has everything but was not happy with his life, found a group online that did ||self-harm|| and wanted to have some adventure in his life, then there was a girl.

#

wont spoil it, but its not a romance xD

#

but its not a movie that encourages/beautifies it, it actually only shows the ugly part, and in a very dark and realistic way

#

TLDR; Sad rich teenager get involved in bad things

#

amazing acting from both lead actors, and every other actor as well

marble shale
#

sounds interesting, but very dark. I'm sure it's good if it won awards.

#

Modding Q!

dusty berry
#

go for it!

marble shale
#

How's this look

    if (ManeuverNodeControllerMod.Instance.currentTarget != null)
    {
      if (ManeuverNodeControllerMod.Instance.currentTarget.Orbit.referenceBody == MNCUtility.activeVessel.Orbit.referenceBody)
      {
        SnapToANtButton.style.display = DisplayStyle.Flex;
        SnapToDNtButton.style.display = DisplayStyle.Flex
      }
      else
      {
        SnapToANtButton.style.display = DisplayStyle.None;
        SnapToDNtButton.style.display = DisplayStyle.None
      }
    }```
#

IS Flex the right thing there to turn it on?

dusty berry
#

seems just as good as you can get

#

yes!

marble shale
#

OK then, I'm making progress!

dusty berry
#

I'll look into Extensions, and PR them to UITK for KSP2 so that we can do something like
SnapToANtButton.Display(false)

#

this for any visual element

marble shale
#

Unity Editor Q, is there an easy way to grab abunch of stuff and group it in an container?

dusty berry
#

well you can shift select things on the hierarchy

#

tho

#

unity has a wierd thing

#

it seems to copy/paste things reversed

#

so your 1st element will be the last

#

Tho!

#

maybe you can just add a visual element about the root one?

#

i dont know if it will work tho

marble shale
#

I've noticed it can be a bit difficult to drag things around and get them where you want. Much easier to drag them where you don't wnat them

dusty berry
#

but now you know that the project's hierarchy matters xD

marble shale
#

Yes it does

dusty berry
#

xD it really is! thats the downsides of using an old version of UITK

#

but its the latest we have for this unity version

#

i think that maybe we can in the future update UITK's version to something like 2021 or 2022 (and a way that wont break mods)

#

but lets keep things like this for now since it works and works well most of the times

marble shale
#

I'm just happy to have what we've got!

dusty berry
#

oh btw

#

you can have uxml files inside uxml files

#

i dont know if you should try xD because you have a window with a LOT of things in

#

but if you right click in hierarchy you can create a template

#

that will create a new .uxml file with that contents

marble shale
#

Interesting

dusty berry
#

this is useful ie when you have a lot of modules that add to each other(or that can be toggled)

#

not so much for your cas,e but you can still use it if you so desire

#

probably for FP you can take a shot at it

#

each tab being its own template

marble shale
#

That would make a lot of sense I suspect. I think I'll want to explore that!

dusty berry
#

great! when u come to it i'll be here to help you!

#

oh btw, you were asking about showing things compactely in UITK like ie your current window

#

the main thing for this is lower font size, but with that comes less readablity

#

i always found IMGUI ui hard to read since the font is 1 pixel wide

#

but you can deffinetly achieve the same on UITK and with the text being renderered in a better way than IMGUI (this is all backend stuff)

#

also the fact that you can choose whatever font you want also will help a lot, there's fonts made to be readable when small

marble shale
#

Hey @dusty berry I took a shot at the top level visual container thing and I was able to make something I thought would work in Unity, but I'm getting errors when I try to call it. In Unity I've got this structure

dusty berry
#

you mean your code in game is giving you errors?

marble shale
#

In my code I'm doing this

private void Update()
  {
    List<ManeuverNodeData> nodes = NodeManagerPlugin.Instance.Nodes;

    // If we've got nodes...
    if (nodes.Count > 0)
    {
      HasNodesGroup.style.display = DisplayStyle.Flex;
      NoNodesGroup.style.display  = DisplayStyle.None;
...
    }
    else
    {
      HasNodesGroup.style.display = DisplayStyle.None;
      NoNodesGroup.style.display = DisplayStyle.Flex;
    }
  }```
marble shale
#

Also the GUI comes up before I've loaded a game

dusty berry
#

Update runs sooner than the window is created (i think)

#

you could add something like a

private bool initialized = false;

//On the end of the InitializeElements
intialized = true;

//on Update
if(initialized)
#

tho wait

#

it can be that its not finding your groups

#

can you send me the code where u assign those 2 variables?

marble shale
#
public void InitializeElements()
  {
    // Set up variables to be able to access UITK GUI panel groups quickly (Queries are expensive)
    NoNodesGroup     = _container.Q<VisualElement>("NoNodesGroup");
    HasNodesGroup    = _container.Q<VisualElement>("HasNodesGroup");```
#

And defined here

public class MncUiController : KerbalMonoBehaviour
{

  private VisualElement _container;

  private float largeStepDv;
  private float smallStepDv;
  private float absDvValue;
  private float largeStepTime;
  private float smallStepTime;

  VisualElement NoNodesGroup;
  VisualElement HasNodesGroup;```
dusty berry
#

okok a sec

marble shale
#

The initialized code stopped the errors, but not it never updates even when it should

dusty berry
#

are you setting intialized = true?

marble shale
#

Yes, at the very end of Initialized

#

    _container.Q<Button>("DecreaseOrbitButton").clicked += () => IncrementOrbit(-1);
    _container.Q<Button>("IncreaseOrbitButton").clicked += () => IncrementOrbit(1);

    initialized = true;
  }```
dusty berry
#

then its not getting to there

marble shale
#

And I check it like this

 private void Update()
  {
    if (!initialized) return;

dusty berry
#

have you checked for errors?

#

on KSP2?

marble shale
#

I'll double check now.

dusty berry
#

np if you want i can take a look at the ksp2 log too

#

also

#

well lets see first if there's any significant erorr

marble shale
#

In KSP log the only places error shows up are here
[ERR 07:54:04.196] AssetProvider unable to find assets with label 'language_source'.
UnityEngine.Debug:LogError (object)
KSP.Assets.AssetProvider/<>c__DisplayClass20_01<I2.Loc.LanguageSourceAsset>:<LoadByLabel>b__0 (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle1<System.Collections.Generic.IList1<I2.Loc.LanguageSourceAsset>>) DelegateList1<UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle1<System.Collections.Generic.IList1<I2.Loc.LanguageSourceAsset>>>:Invoke (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle1<System.Collections.Generic.IList1<I2.Loc.LanguageSourceAsset>>)
UnityEngine.ResourceManagement.ResourceManager:Update (single)
MonoBehaviourCallbackHooks:Update ()
[LOG 07:54:04.200] [System] Loading localizations from Addressables completed in 0.0109s.
...
[ERR 07:54:04.827] [System]
UnityEngine.Debug:LogError (object)
KSP.Logging.KspLog:Error (KSP.Logging.LogFilter,object)
KSP.Logging.GlobalLog:Error (KSP.Logging.LogFilter,object)
KSP.Game.Flow.SequentialFlow:OnActionReject (KSP.Game.Flow.FlowAction,string)
KSP.Game.Flow.FlowAction/<>c__DisplayClass13_0:<Do>b__1 (string)
SpaceWarp.Patching.LoadingActions.InitializeModAction:DoAction (System.Action,System.Action1<string>) KSP.Game.Flow.FlowAction:Do (System.Action1<KSP.Game.Flow.FlowAction>,System.Action`2<KSP.Game.Flow.FlowAction, string>)
KSP.Game.Flow.SequentialFlow:NextFlowAction ()
KSP.Game.Flow.SequentialFlow:Update ()
[LOG 07:54:04.901] [System] Initialization for plugin Cheat Menu completed in 0.0636s.

dusty berry
#

bhot are notmal dw

#

damn i rlly butchered that

#

both are normal*

marble shale
#

There are errors in the BIE log, but the are mostly like this
[Error :CustomizableUI.Utility] Error trying to load data. Full error:
System.NullReferenceException: Object reference not set to an instance of an object
at CustomizableUI.Utility.LoadData () [0x0001b] in <4733a2dc16f74f4baf3c58b1b070a514>:0
[Error :CustomizableUI.Manager] Error initializating top level groups.
System.NullReferenceException: Object reference not set to an instance of an object
at CustomizableUI.TopLevelGroup..ctor (System.String groupName, System.Int32 transformIndex) [0x0002c] in <4733a2dc16f74f4baf3c58b1b070a514>:0
at CustomizableUI.GameView..ctor () [0x00000] in <4733a2dc16f74f4baf3c58b1b070a514>:0
at CustomizableUI.Manager.CreateGroups () [0x00006] in <4733a2dc16f74f4baf3c58b1b070a514>:0
at CustomizableUI.Manager.Initialize () [0x00000] in <4733a2dc16f74f4baf3c58b1b070a514>:0
[Error :CustomizableUI.Utility] Error trying to load data. Full error:
System.NullReferenceException: Object reference not set to an instance of an object
at CustomizableUI.Utility.LoadData () [0x0001b] in <4733a2dc16f74f4baf3c58b1b070a514>:0

#

I don't see any errors actually from MNC in the BIE log

#

FP reports that MNC is loaded and BIE seems to be OK with it

#

[Info :Addressables Loader] Loading addressables for Maneuver Node Controller
[Info :Addressables Loader] Did not find addressables for Maneuver Node Controller
[Info :Space Warp] Attempting to load localizations from C:\Kerbal Space Program 2 Debug\BepInEx\plugins\maneuver_node_controller\localizations
[Info :Space Warp] C:\Kerbal Space Program 2 Debug\BepInEx\plugins\maneuver_node_controller\localizations does not exist, not loading localizations.

dusty berry
#

yeah no errors for MNC

#

then i think that this might be it

#

if not then munix can help

#

swConsole.gameObject.Persist();

#

to your VisualTreeAsset

#

i dont recall the name tho

#

its that thing you did Window.Create() on

marble shale
#

Looking for that now. BTW, the close button doesn't work - has no effect when you click it

  private void SetEnabled(bool newState)
  {
    if (newState) _container.style.display = DisplayStyle.Flex;
    else _container.style.display = DisplayStyle.None;

    //interfaceEnabled = newState;
    //GameObject.Find(ToolbarFlightButtonID)?.GetComponent<UIValue_WriteBool_Toggle>()?.SetValue(interfaceEnabled);
  }```
#

is it part of this?

  public void SetupDocument()
  {
    var document = GetComponent<UIDocument>();
    if (document.TryGetComponent<DocumentLocalization>(out var localization))
    {
      localization.Localize();
    }
    else
    {
      document.EnableLocalization();
    }

    _container = document.rootVisualElement;
    _container[0].CenterByDefault();
    _container.style.display = DisplayStyle.None;

  }```
#

I'm not finding Window.Create()

#

pretty much all the code is either in Update, or in InitializeElements

#

I added this to the end of InitializeElements

    initialized = true;
    ManeuverNodeControllerMod.Logger.LogInfo($"UITK GUI Initialized. initilized set to {initialized}");
  }```
#

And that text is not showing up in my BIE log

#

At least not when I quick at the main menu before entering a game

#

If it's crashing inside there then there ought to be something in KSP2.log, right?

dusty berry
#

sorry for being a bit off!

dusty berry
marble shale
#

None of the logging messages I've put in are coming out. At least not in the BIE log

#

I need to get going (work), but I'll be back to this later tonight. Thanks!

marble shale
#

One final clue, then I'm off... I tried this in Update

  private void Update()
  {
    if (!initialized)
    {
      InitializeElements();
      return;
    }```
And I got a spaming of this in the BIE log
`
[Info   :Maneuver Node Controller] Starting UITK GUI Initialization. initialized is set to False
[Info   :Maneuver Node Controller] Starting UITK GUI Initialization. initialized is set to False
[Info   :Maneuver Node Controller] Starting UITK GUI Initialization. initialized is set to False
[Info   :Maneuver Node Controller] Starting UITK GUI Initialization. initialized is set to False
[Info   :Maneuver Node Controller] Starting UITK GUI Initialization. initialized is set to False
[Info   :Maneuver Node Controller] Starting UITK GUI Initialization. initialized is set to False
[Info   :Maneuver Node Controller] Starting UITK GUI Initialization. initialized is set to False
[Info   :Maneuver Node Controller] Starting UITK GUI Initialization. initialized is set to False
[Info   :Maneuver Node Controller] Starting UITK GUI Initialization. initialized is set to False
[Info   :Maneuver Node Controller] Starting UITK GUI Initialization. initialized is set to False
[Info   :Maneuver Node Controller] Starting UITK GUI Initialization. initialized is set to False
[Info   :Maneuver Node Controller] Starting UITK GUI Initialization. initialized is set to False
[Info   :Maneuver Node Controller] Starting UITK GUI Initialization. initialized is set to False
[Info   :Maneuver Node Controller] Starting UITK GUI Initialization. initialized is set to False`
#

Which means it's one of two lines shown below that's causing the issue

  public void InitializeElements()
  {
    ManeuverNodeControllerMod.Logger.LogInfo($"Starting UITK GUI Initialization. initialized is set to {initialized}");

    // Set up variables to be able to access UITK GUI panel groups quickly (Queries are expensive) 
    NoNodesGroup = _container.Q<VisualElement>("NoNodesGroup");
    HasNodesGroup    = _container.Q<VisualElement>("HasNodesGroup");

    ManeuverNodeControllerMod.Logger.LogInfo($"Panel groups initialized. initialized is set to {initialized}");```
#

Since it never makes it to the second log output line

dusty berry
#

huh

#

btw im assuming

#

you've build a new AssetBundle

#

with the new names right?

#

and didnt change

#

any of the folder of file names

marble shale
#

Yes, but I can build it again.

dusty berry
#

no need

marble shale
dusty berry
#

it seems like its not finding what ur looking for

marble shale
#

I agree. that seems likely

dusty berry
#

wait

marble shale
#

I'm now getting this in KSP2.log

#

[Info :Maneuver Node Controller] Starting UITK GUI Initialization. initialized is set to False
ArgumentNullException: Value cannot be null.
Parameter name: e
at UnityEngine.UIElements.UQueryExtensions.Q (UnityEngine.UIElements.VisualElement e, System.String name, System.String className) [0x00003] in <b04b98aef47f4637b950c1b3349ee421>:0
at UnityEngine.UIElements.UQueryExtensions.Q[T] (UnityEngine.UIElements.VisualElement e, System.String name, System.String className) [0x0001b] in <b04b98aef47f4637b950c1b3349ee421>:0
at ManeuverNodeController.MncUiController.InitializeElements () [0x00021] in C:\KSP2Mods\ManeuverNodeController\ManeuverNodeControllerProject\ManeuverNodeControllerPlugin.cs:1477
at ManeuverNodeController.MncUiController.Update () [0x0000f] in C:\KSP2Mods\ManeuverNodeController\ManeuverNodeControllerProject\ManeuverNodeControllerPlugin.cs:1276

dusty berry
#

Whats on your line 1477?

#

ManeuverNodeControllerPlugin.cs:1477

marble shale
#

NoNodesGroup = _container.Q<VisualElement>("NoNodesGroup");

#

The first suspect naturally

#

And I just now re-built the bundle

#

After making sure I'd saved the Unity project (meaning closed, clicked yes to save, reopened, built)

#

Is VisualElement the wrong type?

#

It can't be, I can see on the hierarchy that's what it is

#

And the inspector

#

I gotta head to work. I'm sure this is something simple. We know where it's bombing now.

dusty berry
dusty berry
#

it could be that in the uxml the name is different

#

and the uxml is what dictates most of this

dusty berry
#

@shadow tree btw whenever @marble shale is back is you could help him with this MisatoPray

#

i THINK that's just addin Persist() on his gameObject but im not sure

shadow tree
dusty berry
#

yeah and i think thats whast happening to him

shadow tree
#
using UnityEngine;

namespace SpaceWarp.InternalUtilities;

internal static class InternalExtensions
{
    internal static void Persist(this UnityObject obj)
    {
        UnityObject.DontDestroyOnLoad(obj);
        obj.hideFlags |= HideFlags.HideAndDontSave;
    }
}
dusty berry
#

oh ok hmm

#

not a good idea to make it public but hmm

#

the thing is, this might actually be a problem for UITK windows

shadow tree
#

I can at least add it to UitkForKsp2 and call it by default on all the gameobjects I create

dusty berry
#

bcuz the controller cuild be getting destroyed when loading the game

#

sure that'd work

#

first lets see if thats actually the problem

dusty berry
#

why?

shadow tree
#

before we added it in SpaceWarp, it would mean that no mods would ever load

#

but they did

#

they just got destroyed only after you were already in-game and then left back to the main menu

dusty berry
#

??

#

that makes no sense wtf

shadow tree
#

don't ask me lol

#

it's how it was

dusty berry
#

well dont destroy on load happens as you said on Load of a game

#

and going back to the menu

#

cuz thats the only times it changes scenes

#

maybe his is somehow getting destroyed when loading a save??

#

lets see

shadow tree
#

you can just try to remove the call from the mod list or console and see what it does

#

but I'm off to bed

#

and tomorrow I need to actually work, I have been slacking off for like two full weeks now

#

and I have a deadline on Thursday for a thing I haven't even started yet

#

lmao

dusty berry
#

lmao

#

good luck 🙏

hollow tiger
#

Alright I can explain

#

DontDestroyOnLoad gets culled after going from game back to the menu unless the object has a tag called game manager or has hide and dont save set

dusty berry
#

so the persist is not even needed?

#

just the tag?

hollow tiger
#

It is

#

The persist is to make it obvious whats going on

dusty berry
#

oh okok yeah makes sense

hollow tiger
#

And it needs to be in DDOL because otherwise itd definitely be culled

dusty berry
#

yeah since its a child of the current scene

#

every child of the current scene gets destroyed

#

makes sense thx MisatoPray

marble shale
#

@dusty berry here are my latest bundle and the uxml

hollow tiger
#

Asset bundle compression is something else

#

9.64 kb where the uxml is 21.56

dusty berry
#

Hmm ok a sec

marble shale
#

Looks like the uxml has the correct names: <ui:VisualElement name="NoNodesGroup" style="display: none;"> and <ui:VisualElement name="HasNodesGroup">

#

When I comment out the lines that were causing a problem, I just get a new problem right after that on lines there were not a problem before. I'm suspecting now there's an issue with _container

#
  public void InitializeElements()
  {
    ManeuverNodeControllerMod.Logger.LogInfo($"Starting UITK GUI Initialization. initialized is set to {initialized}");

    // Set up variables to be able to access UITK GUI panel groups quickly (Queries are expensive) 
    //NoNodesGroup      = _container.Q<VisualElement>("NoNodesGroup");
    //HasNodesGroup     = _container.Q<VisualElement>("HasNodesGroup");

    ManeuverNodeControllerMod.Logger.LogInfo($"Panel groups initialized. initialized is set to {initialized}");

    // Set up variables to be able to access UITK GUI Buttons quickly (Queries are expensive) 
    SnapToANtButton   = _container.Q<Button>("SnapToANtButton");
    SnapToDNtButton   = _container.Q<Button>("SnapToDNtButton");

dusty berry
#

Where ur doing Window.Crest

#

Create

#

Can u show me the code for that?

marble shale
#

Nowhere

#
  public void SetupDocument()
  {
    var document = GetComponent<UIDocument>();
    if (document.TryGetComponent<DocumentLocalization>(out var localization))
    {
      localization.Localize();
    }
    else
    {
      document.EnableLocalization();
    }

    _container = document.rootVisualElement;
    _container[0].CenterByDefault();
    _container.style.display = DisplayStyle.None;

  }```
#
  private void Start()
  {
    SetupDocument();
  }```
dusty berry
#

Not in that .cd

#

Cs*

#

Its in the mncplugin i believe

marble shale
#

When I search for this string "window.create()" I don't find it anywhere in the file, and it's a one-file mod I believe

dusty berry
#

Remember where u put the bundle’s path?

marble shale
#

Nvm, it's not a one-file mod

dusty berry
#

xD its ok

marble shale
#

however widening the sear to the whole solution still does not find it

dusty berry
#

Go to the onInitialized of your plugin class

#

Theres that code that we made there

marble shale
#
  public override void OnInitialized()
  {
    base.OnInitialized();

    MNCSettings.Init(SettingsPath);

    Instance = this;

    game = GameManager.Instance.Game;
    Logger = base.Logger;

    var mncUxml = AssetManager.GetAsset<VisualTreeAsset>($"{Info.Metadata.GUID}/mnc_ui/mnc_ui.uxml");
    var mncWindow = Window.CreateFromUxml(mncUxml, "Maneuver Node Controller Main Window", transform, true);

    mncWindow.gameObject.AddComponent<MncUiController>();

    GameManager.Instance.Game.Messages.Subscribe<ManeuverRemovedMessage>(msg =>
    {
      var message = (ManeuverRemovedMessage)msg;
      OnManeuverRemovedMessage(message);
    });

    // Setup the list of input field names associated with TextField GUI inputs
    inputFields.Add("Prograde ∆v");
    inputFields.Add("Normal ∆v");
    inputFields.Add("Radial ∆v");
    inputFields.Add("Absolute ∆v");
    inputFields.Add("Small Step ∆v");
    inputFields.Add("Large Step ∆v");
    inputFields.Add("Small Time Step");
    inputFields.Add("Large Time Step");

    Logger.LogInfo("Loaded");
    if (loaded)
    {
      Destroy(this);
    }
    loaded = true;

    gameObject.hideFlags = HideFlags.HideAndDontSave;
    DontDestroyOnLoad(gameObject);

    // _spaceWarpUISkin = Skins.ConsoleSkin;

    // horizontalDivider.fixedHeight = 2;
    // horizontalDivider.margin = new RectOffset(0, 0, 4, 4);

    // Register Flight AppBar button
    Appbar.RegisterAppButton(
        "Maneuver Node Cont.",
        ToolbarFlightButtonID,
        AssetManager.GetAsset<Texture2D>($"{Info.Metadata.GUID}/images/icon.png"),
        ToggleButton);

    // Register all Harmony patches in the project
    Harmony.CreateAndPatchAll(typeof(ManeuverNodeControllerMod).Assembly);
  }```
dusty berry
#

Hm a sec

#

Do mncWindow.DontDestroyOnLoad();

marble shale
#

Is this a problem? The path looks like it may be missing a part

#

So the mnc_ui.uxml is not in ../mnc_ui/, it's in ../mnc_ui/assets/

dusty berry
#

No its right

#

The Assets folder is the root folder in unity

#

So no need to reference it

dusty berry
marble shale
#

This code

    var mncUxml = AssetManager.GetAsset<VisualTreeAsset>($"{Info.Metadata.GUID}/mnc_ui/mnc_ui.uxml");
    var mncWindow = Window.CreateFromUxml(mncUxml, "Maneuver Node Controller Main Window", transform, true);
    mncWindow.DontDestroyOnLoad();```
is saying it need to give it an input argument that's an object
dusty berry
#

A sec then

marble shale
#

it seems to want a UnityEngine.Object called target

#

well, that it's going to call target...

dusty berry
#
        UnityObject.DontDestroyOnLoad(mncWindow);
        mncWindow.hideFlags |= HideFlags.HideAndDontSave;
hollow tiger
#

Yeah, that

marble shale
#

UnityObject doesn't exist

hollow tiger
#

UnityEngine.Object

#

SpaceWarp defines UnityEngine.Object as UnityObject to make it obvious that its not System.Object internally

marble shale
#

Ahhh, this looks better. compiling now

#

[Info :Maneuver Node Controller] Starting UITK GUI Initialization. initialized is set to False
ArgumentNullException: Value cannot be null.
Parameter name: e
at UnityEngine.UIElements.UQueryExtensions.Q (UnityEngine.UIElements.VisualElement e, System.String name, System.String className) [0x00003] in <b04b98aef47f4637b950c1b3349ee421>:0
at UnityEngine.UIElements.UQueryExtensions.Q[T] (UnityEngine.UIElements.VisualElement e, System.String name, System.String className) [0x0001b] in <b04b98aef47f4637b950c1b3349ee421>:0
at ManeuverNodeController.MncUiController.InitializeElements () [0x00021] in C:\KSP2Mods\ManeuverNodeController\ManeuverNodeControllerProject\ManeuverNodeControllerPlugin.cs:1479
at ManeuverNodeController.MncUiController.Update () [0x0000f] in C:\KSP2Mods\ManeuverNodeController\ManeuverNodeControllerProject\ManeuverNodeControllerPlugin.cs:1278

(Filename: C:/KSP2Mods/ManeuverNodeController/ManeuverNodeControllerProject/ManeuverNodeControllerPlugin.cs Line: 1479)

#

Basically still same error

dusty berry
#

🙃

#

The name is right

#

The bundle has it

#

afaik paramenter e is just the exception right @hollow tiger ?

hollow tiger
#

e is the element

dusty berry
#

or could it be that somehow he's passing e?

hollow tiger
#

Read the stacktrace

#

Can you show me line 1479

dusty berry
#

Oh wtf i was thinking argument of Q<Element>(arg) not of the internal call

hollow tiger
#

E is the this VisualElement of the Q<Element>(arg)

dusty berry
#

so _container is whats null then im guessing

marble shale
#

If it matters, vs is graying out UnityEngine prior to Object like I don't need that part.

dusty berry
#

no its just saying that's not needed

marble shale
hollow tiger
#

Can I see the line you are talking about

hollow tiger
marble shale
#
  public void InitializeElements()
  {
    ManeuverNodeControllerMod.Logger.LogInfo($"Starting UITK GUI Initialization. initialized is set to {initialized}");

    // Set up variables to be able to access UITK GUI panel groups quickly (Queries are expensive) 
    NoNodesGroup      = _container.Q<VisualElement>("NoNodesGroup");
    HasNodesGroup     = _container.Q<VisualElement>("HasNodesGroup");

    ManeuverNodeControllerMod.Logger.LogInfo($"Panel groups initialized. initialized is set to {initialized}");```
#

1479 is the NoNodesGroup = line

hollow tiger
#

Where is _container set

marble shale
#
  public void SetupDocument()
  {
    var document = GetComponent<UIDocument>();
    if (document.TryGetComponent<DocumentLocalization>(out var localization))
    {
      localization.Localize();
    }
    else
    {
      document.EnableLocalization();
    }

    _container = document.rootVisualElement;
    _container[0].CenterByDefault();
    _container.style.display = DisplayStyle.None;

  }```
hollow tiger
#

Could initializeeleements be called before setupdocument?

marble shale
#

I have this in Update

  private void Update()
  {
    if (!initialized)
    {
      InitializeElements();
      return;
    }```
#

If initialized is false, it will (and does) call it again

dusty berry
#

OH you moved initialize to update?

#

wait but still

#

shouldnt be called before

marble shale
#

I get smamed with these errors

dusty berry
#

because SetupDocument is on Start()

marble shale
#

I didn't so much "move" it there as I put it there. I don't see it being called anywhere else so I assumed it's called automatically

hollow tiger
#

Alright, and they are in the same monobehaviour

marble shale
#

I gotta go cook dinner. I'll be back in a bit.

#

yes

hollow tiger
#

Are there any exceptions in SetupDocument?

#

Cuz if an exception happens before _container is set, then _container will be null

dusty berry
#

send ur KSP2.log if possible

marble shale
marble shale
dusty berry
#

the problem is elsewhere


[EXC 19:23:54.000] MissingMethodException: void UitkForKsp2.API.Extensions.CenterByDefault(UnityEngine.UIElements.VisualElement)
    ManeuverNodeController.MncUiController.Start () (at C:/KSP2Mods/ManeuverNodeController/ManeuverNodeControllerProject/ManeuverNodeControllerPlugin.cs:1271)
#

is your UITK in game updated?

#

this is something on UITK for KPS2 1.2.0

marble shale
#

That may be it! Looks like I'm on 1.1...

#

I'll update and give it ashot

dusty berry
#

xD seems like the problem something else all along

marble shale
#

We've moved the error!

#

This is a good sign...

#

[Info :Maneuver Node Controller] Starting UITK GUI Initialization. initialized is set to False
[Info :Maneuver Node Controller] Panel groups initialized. initialized is set to False
[Info :Maneuver Node Controller] SnapTo buttons initialized. initialized is set to False
[Info :Maneuver Node Controller] SnapTo labels initialized. initialized is set to False
NullReferenceException: Object reference not set to an instance of an object
at ManeuverNodeController.MncUiController.InitializeElements () [0x00536] in C:\KSP2Mods\ManeuverNodeController\ManeuverNodeControllerProject\ManeuverNodeControllerPlugin.cs:1593
at ManeuverNodeController.MncUiController.Update () [0x0000f] in C:\KSP2Mods\ManeuverNodeController\ManeuverNodeControllerProject\ManeuverNodeControllerPlugin.cs:1278

(Filename: C:/KSP2Mods/ManeuverNodeController/ManeuverNodeControllerProject/ManeuverNodeControllerPlugin.cs Line: 1593)

#

Found an obvious issue on 1593... trying again

#

And now we've moved it again!

#

NullReferenceException: Object reference not set to an instance of an object
at ManeuverNodeController.MncUiController.Update () [0x00866] in C:\KSP2Mods\ManeuverNodeController\ManeuverNodeControllerProject\ManeuverNodeControllerPlugin.cs:1437

(Filename: C:/KSP2Mods/ManeuverNodeController/ManeuverNodeControllerProject/ManeuverNodeControllerPlugin.cs Line: 1437)

#

It now doesn't spam NREs when I launch but it does when I've got it running, and it's only showing me the old IMGUI version, not both

#
      NextLANValue.text = nextLAN;```
#

that's one newest offender, but the great news is that's basically the last line in Update, so we're really close!

dusty berry
#

that isnt set

#

check where u set it

marble shale
#

Another obvious bug found and squasshed

dusty berry
#

xd now you know that if players have this bug what they need to do!

marble shale
#

Now I'm only getting the old GUI...

#

It was both before, but now it's only the IMGUI and not the UITK GUI

dusty berry
#

its probably still hidden

#

thats my guess

#

a sec

marble shale
#

Yeah, I'll have to trace that

dusty berry
#

are you calling _container.style.Display = true?

marble shale
#

Here for sure

  private void SetEnabled(bool newState)
  {
    if (newState) _container.style.display = DisplayStyle.Flex;
    else _container.style.display = DisplayStyle.None;

    //interfaceEnabled = newState;
    //GameObject.Find(ToolbarFlightButtonID)?.GetComponent<UIValue_WriteBool_Toggle>()?.SetValue(interfaceEnabled);
  }
#

Here it's set to none

  public void SetupDocument()
  {
    var document = GetComponent<UIDocument>();
    if (document.TryGetComponent<DocumentLocalization>(out var localization))
    {
      localization.Localize();
    }
    else
    {
      document.EnableLocalization();
    }

    _container = document.rootVisualElement;
    _container[0].CenterByDefault();
    _container.style.display = DisplayStyle.None;

  }```
dusty berry
#

hmmm

marble shale
#

That's it.

dusty berry
#

are you sure that SetEnabled is being called?

#

where are you doing it?

#

you could do it on the Update() of the WindowController

marble shale
#

Looks like I only call it for pressing the close button. This would be the problem

dusty berry
#

xD

marble shale
#

There needs to be a way to call it when the app bar button is pressed

#

or when the hotkey is pressed

dusty berry
#

and there is!

marble shale
#

I think I know how to do that

dusty berry
#

go ahead, if you need help im here!

marble shale
# dusty berry go ahead, if you need help im here!

LOL, another question! I thought I knew what to do and it was obvious, but maybe not so much for me. I'm trying to call it from the main plugin by having ToggleButton call it.

  private void ToggleButton(bool toggle)
  {
    interfaceEnabled = toggle;
    GameObject.Find(ToolbarFlightButtonID)?.GetComponent<UIValue_WriteBool_Toggle>()?.SetValue(interfaceEnabled);
    MncUiController.SetEnabled(toggle);
  }```
I made SetEnabled a public method, so it is accessible, but now vs is telling me "An object reference is required for the non static field, method, or property"
#

Do I need to make it a static method?

#

That seems to mess up other stiff, so probably not

dusty berry
#

you do have to make either static

#

or you have to save an instance somewhere

#

u can just save an instance on the plugin class

#

since there's where u first instantiate it

#

and thats also the best way for you to do it

marble shale
#

like this maybe?

#
MncUiController controller = new MncUiController();```
dusty berry
#

nono

#

controller = mncWindow;

#

:D

#

remember that you insntantiate it with Window.CreateFromUxml?

#

sorry actually i think it aint this xD

#

a sec

#

controller = mncWindow.gameObject.AddComponent<MncUiController>();

#

this

#

you have that line on your OnInitialized

#

the AddComponent<>() returns what youre adding

marble shale
#

like this?

  public override void OnInitialized()
  {
    base.OnInitialized();

    MNCSettings.Init(SettingsPath);

    Instance = this;

    game = GameManager.Instance.Game;
    Logger = base.Logger;

    var mncUxml = AssetManager.GetAsset<VisualTreeAsset>($"{Info.Metadata.GUID}/mnc_ui/mnc_ui.uxml");
    var mncWindow = Window.CreateFromUxml(mncUxml, "Maneuver Node Controller Main Window", transform, true);
    UnityEngine.Object.DontDestroyOnLoad(mncWindow);
    mncWindow.hideFlags |= HideFlags.HideAndDontSave;
    mncWindow.gameObject.AddComponent<MncUiController>();

    controller = mncWindow.gameObject.AddComponent<MncUiController>();```
dusty berry
#

no need to call it twice!

#

actually if you call it twice you'll have 2 controllers

#

you only want 1

marble shale
#

I already had the mncWindow.gameObject.AddComponent<MncUiController>(); line, it was there before...

dusty berry
#

oh yeah, but you werent storing it

#

baiscally just remove the 1st one

#

and you're set

marble shale
#

And now maybe ToggleButton will work

dusty berry
#

then you call controller.SetEnabled(ToggleValue)

#

dont forget that

#

when you press the toggle on the AppBar

marble shale
#

Bingo!

dusty berry
#

you have to SetEnabled your controller

marble shale
dusty berry
#

:D

marble shale
#

One press = two GUIs

#

And the;ve got the right info!

dusty berry
#

also the values seem to be working

#

tho i see the problem on the textfields again :(

marble shale
#

Well, mostly... Some things in the new one are a bit off

#

Yes, that and the Maneuver Node In 9 orbits part

dusty berry
#

i think ur ussclass is being overriden by smth

marble shale
#

Should be in 0 orbits

dusty berry
#

youre feeding something wrong to it then

marble shale
#

Oh I see an issue! Thenew one isn't getting the right UT, or maybe not getting UT at all

#

The start time for thenodes are very different

#

The should take Node.Time - UT

dusty berry
#

btw you can do TextField.value = smth to update its value, as you can see, now is at 00.00 in the new window

marble shale
#

I think I can track down most of this madness, but I'm not sure what's up with the text input fields. They look fine int he Unity editor

dusty berry
#

yeah my guess is they are being overriden by something

#

probably uss on the KerbalUI (main ui of UITK for KSP2)

marble shale
#

Could be. The close button does work, none of the others work yet. Still, this is very close. The text inputs are basically getting a huge verticle squeeze. The look OK more or less on width maybe, but top and bottom are getting crushed

#

Is that padding or margin, I cna never recall

dusty berry
#

neither can i xD

#

but i think its margin

#

margin is for the object inside the visual element

#

padding is for the objects outside

#

basically
padding = the surrouding garden of a house
Margin = How thick the walls are

marble shale
#

Ok, then margin is getting set wrong somehow

dusty berry
#

while the visual element is the house 🙏

dusty berry
#

let me take a look at the uss, can i?

#

you might need to target a more specific class

#

the more specific the class is higher its priority

dusty berry
#

hmm

#

.unity-base-text-field__input

#

try changing this to a selector

#

so

#

.unity-text-field > .unity-base-text-field__input

#

also change the one just about that
.text-input to .unity-text-field

marble shale
dusty berry
#

basically you're making it more deterministic, thus it will have more priority

#

this is mostly as a hail mary to see if it really is KerbalUI that's messing your UI

marble shale
#

I've now got both of these defined, and they're identical defs I think

#

But I don't know how to do the other one

#

I mean, all those things are selectors, right?

#

Oh, wait, I think you're really jsut saying make another selector and name it .unity-text-field, or can I rename the one I've got?

dusty berry
#

well both will work

#

you can keep the old ones if you'd like

#

but renaming might be the right way to go at it

marble shale
#

OK, let me see if I understand this. Change the name of .text-input to be .unity-text-field, right?

dusty berry
#

yes

#

actually

#

.text-input

#

shouldn't even be targeting anything

#

unless you added it to the elements

marble shale
#

I did add it. It does target things

dusty berry
#

.text-input {
    flex-direction: row;
    justify-content: space-between;
    width: 290px;
    margin-left: 2px;
    margin-right: 2px;
    margin-top: 2px;
    margin-bottom: 2px;
    flex-grow: 1;
}
#

oh okok

#

tho lets see if this will work

marble shale
#

Wait, I'm still confused. The second thing you suggested sounds like it steps on the first thing - I'm probably misunderstanding...

#

If I Change the name of .text-input to be .unity-text-field, and I change the name of .unity-text-field > .unity-base-text-field__input am I not just changing one thing twice?

#

I've got a def for .unity-base-text-field__input already in there

#

Here's what one of the text fields looks like for it's styles

dusty berry
#

nono

#

.unity-text-field > .unity-base-text-field__input

#

this

#

is a selector

#

you are selecting

#

any of its 1st childs

#

with that tag

#

so any of .unity-text-field first childs

#

with the .unity-base-text-field__input class

marble shale
#

Like this then?

dusty berry
#

yes

marble shale
#

I had no idea you could even do that...

dusty berry
#

well its all on that pop up!

#

you can do much more

marble shale
#

Which might be written in greek, I'm not sure

dusty berry
#

xD

#

you can also select by name as you done there

#

and you can select any child (recursively)

#

if you remove the >

#

you can also target any TextField, Button, Label etc by writting the class name

marble shale
#

OK, I renamed the other one and curiously now it's not targeting anything where before it was

dusty berry
#

4th entry is what you just did

dusty berry
marble shale
#

I see that, but I had no idea what it meant. I'm probably not grasping it yet either. Is it saying this-thing overrides/trumps that-thing?

dusty berry
#

the second one should be this

marble shale
dusty berry
#

OH

#

sorry

#

i thought it was the other one who was having problems

#

youre trying to target this

#

you have a typo there xD

#

idk if you copied from me, might have been i do make alot of typos

#

yours say feild

marble shale
#

That was my error I'm certain. Changing it restored the targeting to what it was.

#

I'll save, rebundle, and give this a shot.

#

I've got some other thigns to test as well where most of the new buttons should be working now

dusty berry
#

great!

#

i think that this was your exact problem btw

#

since KerbalUI has a selector just like yours

#

and it can very likely be overriding yours that was less specific

marble shale
#

Sadly, no...

dusty berry
#

this is very wierd :/

#

btw is everything else working?

marble shale
#

Some, there's an issue with my AddNode. I need to test some other thigns though

dusty berry
#

well you can change it via code, that's the highest priority

#

tho either me or munix will have to scavange the code to see where the issue is

#

let me see what you'll do to set it via code

marble shale
#

Some things work, but with the text fields goofed up, it's really hard to tell if the increment/decrement burn buttons work

dusty berry
#

interesting

#

its not padding thats doing that

#

or better

#

its not margin thats doing that

#

rather its actually either padding or smth else

marble shale
#

When you say change it by code, do you mean maybe go into InitilzeElements and set it from there?

dusty berry
#

yes

#

tho you might need reflection for this... i'll help u out w it tho

#

or if you rather wait for munix, im sure that he'll know something aoubt this (maybe xD)

#

as he knows more about css and wrote the KerbalUI.uss

marble shale
#

Isn't he going on a game sabatical to do his real work?

dusty berry
#

oh true 🙃

marble shale
#

There are a couple of odd things going on with the GUI other than the text fields. For some reason the start time for node[0] (index 1) is messed up, bot other nodes are not

dusty berry
#

not when its initialized!

marble shale
#

Also, the main GUI correctly sees there is not target and so doens't display the ANt or DNt buttons, however the UITK GUI is showing them, when it shold not be

dusty berry
#

then the ANtButton.display is not being set to None!

marble shale
#
      // If we've got a target
      if (ManeuverNodeControllerMod.Instance.currentTarget != null)
      { // If that target is orbiting the same body the active vessel is
        if (ManeuverNodeControllerMod.Instance.currentTarget.Orbit.referenceBody == orbit.referenceBody)
        { // Allow SnapTo ANt and DNt
          SnapToANtButton.style.display = DisplayStyle.Flex;
          SnapToDNtButton.style.display = DisplayStyle.Flex;
        }
        else
        { // Do not Allow Snap To ANt or DNt
          SnapToANtButton.style.display = DisplayStyle.None;
          SnapToDNtButton.style.display = DisplayStyle.None;
        }
      }```
#

I think I see the problem!

#

It should be this!

      // If we've got a target
      if (ManeuverNodeControllerMod.Instance.currentTarget != null)
      { // If that target is orbiting the same body the active vessel is
        if (ManeuverNodeControllerMod.Instance.currentTarget.Orbit.referenceBody == orbit.referenceBody)
        { // Allow SnapTo ANt and DNt
          SnapToANtButton.style.display = DisplayStyle.Flex;
          SnapToDNtButton.style.display = DisplayStyle.Flex;
        }
        else
        { // Do not Allow Snap To ANt or DNt
          SnapToANtButton.style.display = DisplayStyle.None;
          SnapToDNtButton.style.display = DisplayStyle.None;
        }
      }
      else
      { // Do not Allow Snap To ANt or DNt
        SnapToANtButton.style.display = DisplayStyle.None;
        SnapToDNtButton.style.display = DisplayStyle.None;
      }```
#

I had nothing actually handling the case when currentTarget == null!

dusty berry
#

well

#

to fix this

#

you could set their display to None in the uxml

marble shale
#

I was only switchingoff if it was not null and the target was not in the same SOI

dusty berry
#

this way their default state is hidden

#

Yeah, but the root is them bein enabled

#

even tho their main state is disabled

#

that works tho!

marble shale
#

If it's set that way and you run around selecting and unselecting targets what happens?

#

I think this way is fool proof

dusty berry
#

well true!

marble shale
#

Now to see why my time is messed up

#

It really shouldn't be... It's just this one line regardless of what's happening

      StartTimeValue.text = MNCUtility.SecondsToTimeString(thisNode.Time - UT, false);
#

with this defined above

      int selectedNode = ManeuverNodeControllerMod.Instance.SelectedNodeIndex;
      ManeuverNodeData thisNode = nodes[selectedNode];```
#

And I know thisNode is working as I use it for basically everything, like displaying the bur vector components - which are comingout right

dusty berry
#

oh yeah makes sense

#

its always the smallest things xD

marble shale
#

I kinda sorta fixed the text inputs. I brute forced it. Went in and just set margin =2 and padding =0 on the text input elements themselves. Why fight with it? Using styles is great when they work, but if they don’t work then fuck ‘em

#

Still not sure what’s up with the time display. It’s sort of like there’s a lag on setting the node index or getting the node info. Probably not that, but weird. I’m headed for bed. I’ll play with it more tomorrow. I know its close now

dusty berry
#

i'd said yet again that maybe you're missing something in code, the label just shows what you want it to show, there's no delay on it (unless you make the dealy yourself)

marble shale
dusty berry
#

xD

marble shale
#

That said, I've also tracked down why none of my burn time adjust buttons were working. Turns out they were working, but what was going wrong was that variables that are supposed to have the values used were not being initialzed and were all zero, so it acted like the buttons didn't work, when they did

dusty berry
#

as always the smallest things

dusty berry
#

can u put a log inside the "TryParse"?

marble shale
#

It's not that. The issue was that although the GUI starts by showing you a default value in the text field, it doesn't actually do anything with that default value unless you change it. If you do change it, then the new value gets into the variable and all works fine. So, where we had this

    _container.Q<TextField>("AbsoluteDvInput").RegisterValueChangedCallback((evt) => {
      if (float.TryParse(evt.newValue, out float newFloat))
      {
        _container.Q<TextField>("AbsoluteDvInput").style.color = Color.white;
        absDvValue = newFloat;
      }
      else
      {
        _container.Q<TextField>("AbsoluteDvInput").style.color = Color.red;
      }
    });```
#

I've now got this

    pass = float.TryParse(_container.Q<TextField>("AbsoluteDvInput").value, out float absDvValue);
    _container.Q<TextField>("AbsoluteDvInput").RegisterValueChangedCallback((evt) => {
      if (float.TryParse(evt.newValue, out float newFloat))
      {
        _container.Q<TextField>("AbsoluteDvInput").style.color = Color.white;
        absDvValue = newFloat;
      }
      else
      {
        _container.Q<TextField>("AbsoluteDvInput").style.color = Color.red;
      }
    });```
#

The idea being that when we initilze things we also want to set the values for these variables.

#

That said, this first attempt is not working 😕

#

Oh! I see the problem! Where I tried this

pass = float.TryParse(_container.Q<TextField>("AbsoluteDvInput").value, out float absDvValue);```
I actually needed this!
```cs
pass = float.TryParse(_container.Q<TextField>("AbsoluteDvInput").value, out absDvValue);```
#

I was redeclaring the damn things!

#

Nuts... This still doesn't work

dusty berry
#

im 99% sure

marble shale
#

All of these

  private float largeStepDv;
  private float smallStepDv;
  private float absDvValue;
  private float largeStepTime;
  private float smallStepTime;```
are starting out as zero, and the code I've added in `InitializeElements` is not correcting this
dusty berry
#

what are they suposed to start at?

#

the value on the Input?

marble shale
#

the small steps should all be 5 and the large should all be 25

dusty berry
#

im guessing that the value on the input starts at 0 too

#

ok lets do it like this then

dusty berry
marble shale
#

The text in the GUI textfield is all showing up ok.

dusty berry
#

but the thing is

dusty berry
#

so until you interact with it it will stay 0

#

thats problem 1

#

have u tried interacting with it? does it work well after you interact?

marble shale
dusty berry
#

what i'll recommends you is

#

to reduce maintenance work on it

#
_container.Q<TextField>("AbsoluteDvInput").value = absDvValue.ToString();
#

on InitializeElements

#

this way if you change that value on code it will update in game as well

dusty berry
#

this way if you want to such a minor change to the ui you can just change it in code

#

then

#

it should start working as normal

dusty berry
#

the problem with what ur doing there is if the TryParse fails your problem will be back

#

while if you feed it directly a float absDvValue it will always be a valid value

marble shale
#

I only know that what I tried with the TryParse experiment didn't actually work. I think this new way will though. I'm going to try it.

dusty berry
#

it ididnt because i suspect you did it wrong, but still wouldnt be a "will work forever" solution

#

this would be the right way
float.TryParse(_container.Q<TextField>("AbsoluteDvInput").value, out absDvValue);

#

but again, this is dependent on what you've put on the uxml

marble shale
#

Yep, I found that issue: #1114994858017423460 message

#

But even taking out the erronious redeclaration didn't get it to work

dusty berry
#

its probably not being able to parse it

#

when you're doing something like that

#

where you're not using the TryParse in a if statement

#

its better to use

#

absDvValue = float.Parse(_container.Q<TextField>("AbsoluteDvInput").value);

#

as this will throw an exception if it isnt able to parse

marble shale
#

It's mostly working now. This part, the burn vector and time adjustment part, seems to be working perfectly. There is some sort of weird lingering problem with the node creation part.

dusty berry
#

hm whats actually happening on it?

marble shale
#

It used to be that I could create up to 9 nodes on one trajectory without issue. Now when I get to like the 4th or 5th one everything goes bonkers and I get red text all over the screen.

dusty berry
#

seems like you are creating the nodes 2x

#

since it stops working at exactly half of it xD

marble shale
#

LOL, that may actually be true! I just tried with the IMGUI version and it crapped out on the 5th node too!

dusty berry
#

as i suspected xD

#

jk

marble shale
dusty berry
#

so thats something like

#

the List has 5 nodes, and you're trying to access a 6th node

#

basically youre passing an index that doesnt exist

marble shale
#

It used to do this to me back when I was first making MNC work with multiple nodes. I got it fixed, and in the process moved the node management into Node Manager so I wouldn't have to fix both MNC and FP. Now it's back again

dusty berry
#

could be Node Manager

#

but doubt

marble shale
#

It bombed on making the 5th node. The reason it got to 5 of 6 before was that it had started with one node

dusty berry
#

since i guess you havent messed with it

marble shale
dusty berry
#

oh i see yeah

marble shale
#

I'm gonna roll back to a previous MNC and make sure it's just this one.

#

Well nuts...

#

It bombed

#

I have apparently re-intproduced the problem - quite possibly in NM and I just didn't test it enough. I'm going to roll it back and see

dusty berry
#

oh damn those are the worst

#

:s

#

good luck!

marble shale
#

Confirmed gone in NM 5.4 (published on 5/18), and MNC 0.9.2

dusty berry
#

maybe just revert?

marble shale
#

MNC 0.9.3 requires NM 5.5, so I can't tell if there's any problem there.

#

Well... NM 5.5 does have some things I need in it, so I think the solution is actually to compare 5.5. and 5.4 and see what changed. The main features I added were the ability to delete just one node or all nodes in the past. Those features should have nothing to do with this. I have a hunch I also did something I'm now regretting in the node creation part.

#

This is gonna be fun... The release notes for NM 5.5 are this.

Updated to bring in MechJeb library functions needed by ManeuverNodeController 0.9.4 and FlightPlan 0.8.9. Node Manager now provides the following things
OrbitExtensions
MathExtensions
MuUtils
MechJebLib\Primatives
MechJebLib\Utils

#

I don't think that's what's breaking it... I must have stepped on something else and forgot to mention it

dusty berry
#

check the commits

#

they show file differences

marble shale
#

But the good nres is that the UITK ver of MNC is not to blame!

dusty berry
#

yes xD the window seems ready to use!

marble shale
#

Relocating to here since this is a general Unity UITK mode kind of question...

#

@dusty berry the place where I'm getting confused with modifying toggles is here

#

There's all this stuff under the toggle, and I kind of don't want it, or don't think I need it - like the checkmark part

#

Selecting the basic unity toggle I see these for styles

#

One level down on the label I see these

#

The visual element has these

dusty berry
marble shale
dusty berry
#

controls are basically a group of uielements controlled by code

#

everything thats created by code you can't delete

#

and yhou can only modify via uss classes

#

you can always just hide the checkmark by setting it to Display. None

marble shale
#

The VisualElement contains the checkmark and when I select it I see this in the GUI

#

So, maybe if I were to override that with a css to make it have 0 width or otherwise just not be there, then I would have a toggle without a check - but then the user cant interact with it. So maybe instead I need to make the label have 0 width and the VisualElement has it all but I need to change it from displaying a chekmark or not to instead change the text displayed and the background for it?

#

It's sounding more and more like I need to stick with a stock button and write the code in my mod to handle it like a toggle. Honestly that sounds easier to me, but maybe becuase I'm new at Unity/css/etc.

shadow tree
#

I mean you can just look at the KerbalUI style for toggles

#

I do a lot of styling magic there to get rid of the checkmark etc

#

it's the .toggle class

marble shale
#

Oooo! This sounds promising! I'll take a look at .toggle in the KerbalUI

shadow tree
#

but I do agree with Lux in that it's not the best UX practice to mask toggles as buttons

marble shale
#

I like the way they behave in the modlist. do I need to replicate this in my uss to get that as a starting point?

#

Or is there a way for me to just use that since it's already in the theme and I may not need to replicate it?

shadow tree
#

all you need is just put the toggle class on your toggles

#

I didn't do it by default for all toggles, because foldouts also contain a toggle and it messes it all up

#

I'll need to take a better look at it when I have some time

marble shale
#

I added KerbalUI.uss to my StyleSheet to see this, but I don't see .toggle on a line by itself, only on the lines I sniped above.

#

How do I "just put the .toggle class on your toggles"?

shadow tree
#

on your elements

marble shale
#

Ordinarily I'd drag the selector to the thing I want to apply it to

shadow tree
#

like you would put any other class on them

marble shale
#

I'm not asking my question very well...

shadow tree
#

just type toggle and press "add"

#

on any toggle element

marble shale
#

Ahh that worked! Figures it was easier than I thought.

#

I've just not done it that way before and didn't realize that's what you meant

shadow tree
#

yeah I'm probably also not the best person to explain it since I only really use the builder for the live preview and otherwise write all the UXML and USS by hand lmao

#

so I don't really know the actual process of using the visual editor

marble shale
#

Is there a way I could get some text inside the toggle part that lights up and also control it's width?

shadow tree
#

you know what they say, where there's a will, there's a way 😛

marble shale
#

LOL, thanks!

shadow tree
#

I can't tell you off the top of my head, I'd have to go and experiment with it

#

but as for the width, that shouldn't be too difficult

#

just look through the KerbalUI .toggle selectors and the width should be set in there somewhere, then you just have to write a similar/slightly more specific selector and overwrite the value

#

though if I remember correctly, the style for the toggle is a bit hacky so it might be in multiple places

marble shale
#

Since I'm going to want some things to be toggles and some to actually be radio buttons, I've got a hunch that in a number of places I may be ahead to make the stock buttons do what I want. A uss solution might be better, but for me I suspect it would take an age - while I could lift the radio button behavior right out of my current code and have something working much sooner.

dusty berry
#

oh fuck