-
Notifications
You must be signed in to change notification settings - Fork 230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A GUI toolkit. #1878
A GUI toolkit. #1878
Conversation
While this is cool, I'm not sure how I feel about leaving the telnet control option out in the cold like this. But I'm not sure how much it matters. I don't really see a lot of people using the telnet option much. Up until now we haven't introduced anything that makes a big difference. I'm a bit torn on whether or not introducing this is good. It's a very cool option I've been wanting for a while, but I've always entertained the notion that it could be do-able entirely on the terminal window itself. |
I was considering the terminal approach, but it takes up a lot of screen realestate (especially with all the settings gadgets on it now). In contrast, having a boot program that starts up a simple custom GUI means kOS users could even develop entire "mods within a mod" for non-kOS users (hmm... ROM modules in Parts.......). As for Telnet, I see these users as an entirely different breed from those who would want to use/write a GUI. How horrible would Windows have been if it had a TTY renderer. I think ultimately people will write useful functions (like "launch to orbit" and "execute node" and "land" that I'm sure we've all written), then bind them to a GUI while still being easily able to execute them from the command line, in the same way that MacOSX is Unix underneath. One thing I forgot to mention is that I had no luck working out how ScopeLost works. It almost never seemed to be called. So I settled for the idea that programs really should manually call Hide() on the window and when power is lost that windows close themselves. |
What I mean is that "here's a list - pick something from it", and "here's a checkbox you could select" are concepts that are not gui-specific in the slightest. People have coded TUI toolkits on top of things like curses that do all that. But that sort of thing is sparse and hard to find in the C# world. But what using the existing gui toolkit buys us is that we don't have to code all the stuff to deal with the user input and updating the visual look based on what the user did, and all that jazz. The fact that it's on a GUI isn't much of an advantage. The fact that if we use the Unity GUI system then the work has been done already by other people, however, is, so I might begrudgingly accept doing it that way even though it helps drive the artificial wedge between interactive and command line usage by making it possible to write scripts that cannot be used from a remote connection. |
Note that while it uses the older Unity IMGUI, it's presented as object-based so should in theory port easily to UGUI should the need arise. Ideally, that abstraction should be kept however it goes forward. |
Fix up documentation (now actually tested to go through sphinx).
Split PADDING into HPADDING and VPADDING Add ADDHLAYOUT and ADDVLAYOUT - like HBOX/VBOX, but default to entirely no style or borders, just pure layout.Honour scoping so that UIs can be usefully made with locals, not just globals. Optimize styles to avoid creating new ones until actually changed. Make LABEL and SLIDER honour HSTRETCH being set to false (and it will now default to false too on LABEL) Tweak initial hslider style.
I suppose I shouldn't be the only one deciding things. I'm just one person and kOS is a team effort that nobody really singly owns. So since it seems the GUI idea is gaining traction it's better to include it rather than keep it as a messy separate fork. (I admit that by adding sound I moved things a bit away from the "remote text allows complete control" direction myself, but sound was a gui-only output thing so it wasn't quite the same situation as having a gui-only input method would be.) In the end, really to be honest, the problem is only a problem because I've been dragging my feet on the text facilities so they're not up to snuff to compete against the easier to implement GUI stuff (easier because, again, the toolkit is right there ready to be used in Unity and not something we'd have to make from scratch.) I mean, I never even implemented a "type a line of text" input to a program yet, and that's really quite basic. So yeah, I shouldn't be objecting to it. It's only a problem of my own making by dragging my feet on implementing the textual alternative. That's no reason to nay-say someone else getting the task done quicker and simpler and (let's be honest) in a way most users probably would prefer anyway. I would at least like to maybe put in a little effort on trying to make the UI look a bit more KOS-like, but that can be done later by manipulating the UI skin settings. It's not a reason to block progress. |
Incidentally, @WazWaz : Can you add an issue to associate with this Pull Request? Our preferred organizational way to deal with major feature enhancements like this is to separate the implementation (PR) from the high level feature description (Issue). Even in cases like this where you already implemented it, it's still nice to submit both, to have the pairing to fit together. (It also helps because it gives a good description of "This is what it needs to do" that's separate from "This just happens to be what I did to get the job done." It makes it more clear what sorts of changes would be more of a deal-breaker for you.) |
I'd like to leave it in a branch for a little longer as I'm still discovering "deep" changes (like the scope thing). When I think it's at least at "beta", that would be a good time to pull to main. Issue: will do. |
Fair enough. Let me tag this PR with the label "Not Ready" then, to remind us not to merge it. I don't know if you have the permissions to alter labels. If you don't then let us know when you do consider it ready and we can remove the "Not Ready" label. |
Revert scope-based widget deletion. Add explicit widget disposal (removal from parent). Make top-level window auto-resize. Fix blank transparent space window margins.
Add "CHANGED" attribute to PopupMenu (like TextField). Make it easy to use objects other than strings in a PopupMenu.
The "Not Ready" can come off. I believe this is now good for release. Of course, I'm happy to be told "do X, Y, and Z first" (eg. I've made sure it's documented, but does it need more examples, tests, or anything?). I'm assuming the big red crosses above are because things unrelated to this branch are causing test failures. |
doc/source/structures/misc/gui.rst
Outdated
HOVER The widget is under the mouse. | ||
ON The widget is on (eg. button is PRESSED). | ||
============= ===================================================== | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started reading through this today a bit and this part is very confusing. You say there are 8 variants of the image but there's only a capacity to select one file mentioned, the BG file. Is the BG_FOCUSED, BG_ACTIVE, etc all just procedurally generated from the one file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm guessing there's some files missing (i.e. the git add
command wasn't run for them). I only see one PNG file for the button, and I don't see any of these suffixes corresponding to any AddSuffix
calls within the C# code (that C# file is probably missing from the PR).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BG_* - It's just trying to shorthand the documentation. There are 8 attributes, but it looked cluttered and confusing to list them all in the normal section, so I put it in a note where they could be properly explained.
I'm not sure which PNG files you mean. There should be some in the documentation, and 3 in the GFX directory:
- commDelay - the "busy" icon
- popupmenu_bg_hover - the yellow color seen on PopupMenus.
- radiobutton - wrong name I just realized, it's the icon for the left side of PopupMenus.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Dunbaratu check here: https://github.com/KSP-KOS/KOS/pull/1878/files#diff-4ac6900d9949c6bfbb7c3bdd9b5b3ec1R93
@WazWaz I get the idea that the various BG suffixes getting confusing, but every suffix really should be documented directly for the sake of consistency and clarity (the few we don't document now eventually need to get updated). If the group of suffixes is confusing, maybe it would make more sense to create some kind of a "background configuration" structure, so that the syntax might get cleaned up like this:
set widget:bgconfig:focused to "myFocused.png"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there are 8 different suffixes, this was not clear from the docs. (Remember that the C# code that implements what this document is talking about is missing from your PR (I saw no calls to AddSuffix
within the diff output listed on the PR page, which probably means the C# file that implements them wasn't git add
-ed to the branch yet. So I only see the docs and not the implementation. (Which is a pretty good test of how understandable the docs are, as that's the situation we should expect a typical user of kOS to be in).
As to the URL you linked, It looks like you have added more to the PR than was there when I looked at it a few hours ago. That file was definitely missing before. I'll go have a look now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They're in src/kOS/Suffixed/Widgets.cs in the original PR (src/kOS/Suffixed/Widget/Button.cs now) - note that github elides it because it's a long file, so CTRL-F won't find it.
Add SKIN to GUI allowing single-point-of-change in styles, and changing of sub-part styles.
I reconsidered what @hvacengi said about a "bg config" structure. I still didn't do that, but moving all the style attributes to their own structure cleans up the structs (and docs) nicely, and the concept of a SKIN comes for free. I'm unsure of the namespace consequences of these GUI elements. I think they should affect users (because only functions should have that problem, of which there is only GUI(width)), and the C# class is "WidgetSkin", not just "Skin", but does the kOS struct name (Skin) have any consequence? |
… while up). Allow BORDER, etc. to be completely specified (left, right, top, bottom), not just H and V.
Add "VISIBLE" for reading HIDE/SHOW state. Tweak radiobuttons to work reliably over comm delay.
Add SELECTIONCOLOR attribute to SKIN. USE configured skin (for other settings like font, etc.)
Looks like your most recent commits are missing the changes to kOS.csproj to account for WidgetStyle.cs and WidgetSkin.cs |
…el." I accidentally committed my local install changes.
I committed them in ffa8408, but accidentally also committed my local "install to KSP" changes, which I've now reverted. |
… copying the whole GUIStyles too, unnecessarily in this case. Save and restore GUISkin around GUI operation (because other GUI might not set anything, eg. dev console).
# Conflicts: # src/kOS/SharedObjects.cs
@WazWaz - can you remove the "Not Ready" label on this PR to state officially that you're okay with merging it now? (Do you have the privileges to change labels in this github? If not then just post a comment telling us to remove the label.) Also, is this up to date? |
Last commit was yesterday: 5e05b1e It looks like he's a member of the "contrib" team, which only has read access to the repository. I assume that applies to labels and such as well. |
In that case, github's presentation is totally bogus. It's indented thusly:
Implying all three of those commits are underneath the heading "some commits on Dec 13th". If they're not all part of that, they shouldn't be indented that way. |
The merge commit from yesterday appear to be included in "Commits" on this PR, but no, I can't edit labels. But I'll say here I believe this is Ready. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some things I noticed recently on my second read-through of this code. (I still intend to approve the PR - these are just notes and questions for comment before I do so.)
The AddTabWidget function should however accept any VBOX as the parameter:: | ||
|
||
LOCAL gui TO GUI(500). | ||
LOCAL tabwidget TO AddTabWidget(gui). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note To self: Just to make it scan better, change the "TO" to "IS" in this and all the other places where the documentation says LOCAL ___ TO ____
.
} | ||
catch(NullReferenceException) | ||
{ | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should there be a return;
in this catch
body?
What is the expected situation where you'd still want to execute the rest of OnGUI() after finding that there was a null in the above code block somewhere? I know that in the case of kOS.Safe.Utilities.SafeHouse.Config if that's not there then most of kOS is going to go wrong and crash anyway. It needs to get set up before the rest of kOS can work. The only thing I don't know about is FlightResultsDialog
-is it normal for that to remain null for a long time during KSP's run? Or is it something that just is null for a short moment during scene changes or reloads?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this was copied from TermWindow.cs, and was part of the initial commit by Nivekk. That being said, it would probably be worthwhile to look into this behavior. It may not be an issue at all anymore, or it may be possible to detect the null reference without throwing an exception (which is expensive, and particularly an issue inside of GUI update methods). At the very least, catching the excepting should log a message of some kind (I'd prefer an error message) so that we can find out if this exception is ever being thrown. I've checked and it looks like internally FlightResultDialog.isDisplaying
includes a null check for the private Instance
field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this was from TermWindow.
src/kOS/Screen/GUIWindow.cs
Outdated
} | ||
|
||
public PopupMenu currentPopup; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have an official standard that says all the member fields and properties are declared up at the top rather than in-line mixed up with the methods? I don't know if we officially state it, but it seems to be the pattern we usually follow. I've noticed in several places in this pull request where they occur sandwiched between methods, usually just before the first method that happens to use the field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While not "gospel", the referenence guidlines state:
Classes member should be alphabetized, and grouped into sections (Fields, Constructors, Properties, Events, Methods, Private interface implementations, Nested types)
I'm not one to get too hung up on it, cause it isn't a huge issue (particularly the alphabetizing). But if most of the fields/properties are declared at the top, it does make it easier to read the file if that location is consistent. I would probably move them if I were doing the review.
@@ -12,15 +12,27 @@ public class SharedObjects : Safe.SafeSharedObjects | |||
public ProcessorManager ProcessorMgr { get; set; } | |||
public Part KSPPart { get; set; } | |||
public TermWindow Window { get; set; } | |||
public List<KOSManagedWindow> ManagedWindows { get; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was it the intention that we move all KOSManagedWindow
s into this list, and manage all of them with the same technique? If so then there are also changes that would have to occur in the popup text editor too, where it uses KOSManagedWindow
objects.
If, on the other hand, it was not the intention to move all KOSManagedWindow
s into this system, and instead we only want to have some of them here, then I'd like to see the name of this changed. The rather generic all-encompassing name ManagedWindows
implies this is where you should be able to find all the Managed Windows, rather than just a subset of them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The TermWindow
would also technically qualify. This list should also be cleared, and the contained windows destroyed with UnityEngine.Object.Destroy
, in the DestroyObjects
method, unless they have no reference to SharedObjets
to create a circular reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally yes, but I didn't want to tread on the code that references SharedObjects.Window. That change should be an Issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm compiling a list of all these "should be addressed, but shouldn't prevent the GUI from being merged" kinds of issues and I added them to the issues list. This is one of them, here: #1952
doc/source/structures/misc/gui.rst
Outdated
:attr:`VERTICALSLIDERTHUMB` :struct:`Style` Style for the thumb of vertical :struct:`Slider` widgets. | ||
:attr:`LABEL` :struct:`Style` Style for :struct:`Label` widgets. | ||
:attr:`SCROLLVIEW` :struct:`Style` Style for :struct:`ScrollBox` widgets. | ||
:attr:`TEXTFIELD` :struct:`Style` Style for :struct:`TextField widgets. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:struct:`Textfield widgets.
This is missing a terminating backtick delimiter. (This showed up in github's diff view because it rendered the rest of this document underlined.)
doc/source/structures/misc/gui.rst
Outdated
LOCAL gui TO GUI(200). | ||
// Add widgets to the GUI | ||
LOCAL label TO gui:ADDLABEL("Hello world!"). | ||
SET label:ALIGN TO "CENTER". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example doesn't match what's in the mod. Label objects have no such suffix "ALIGN".
Example:: | ||
|
||
local popup to gui:addpopupmenu(). | ||
set popup:OPTIONSUFFIX to "NAME". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to read through the C# code several times to finally understand what OPTIONSUFFIX is for. It was really vague and unclear from this documentation. This part of the documentation should explain it a bit better.
Something like this will make more sense:
"The list always displays string values in it. If the list contains items that are not strings, then by default their TOSTRING (link to generic Structure:ToSTRING should go here) suffixes will be used to display them as strings.
You can change this default behaviour by setting the popupmenu's :OPTIONSUFFIX to a different suffix name other than "TOSTRING". In the example below which builds a list of bodies for the pulldown list, the body:name suffix will be used instead of the body:tostring suffix for all the items in the list."
Explicitly mentioning how this setting is an alternative to the default behavior of TOSTRING helps make it more clear what this suffix is doing and why it exists.
doc/source/structures/misc/gui.rst
Outdated
Every suffix of :struct:`BUTTON` | ||
----------------------------------------------------------------------------------- | ||
:attr:`OPTIONS` :struct:`List`(Any) List of options to display. | ||
:attr:`OPTIONSUFFIX` :struct:`string` Name of the suffix that names the options. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest the terse description here again mention that this is in lieu of using TOSTRING:
"Name of the suffix used for display names. Default = TOSTRING".
I'd like a lot more input from others before I'd even want this in kOS of course, but this is presented here for discussion.