Search Unity

Philosophical Issue with GUI architecture...

Discussion in 'Immediate Mode GUI (IMGUI)' started by podperson, Nov 15, 2007.

  1. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    The way that the widgets (Windows in particular, but other containers too) work, you define their size, not their content area. The disadvantage of this is enormous -- you set margins based on one skin, and they won't work in another. None of the sample windows I've built using the default skin look acceptable with any of Shaun's other skins. This isn't how a GUI library should work. This isn't how CSS works.

    E.g. when you define a Window you are defining its entire size. In OS X or Windows or KDE or Gnome or any other sensible system you define the content area, and the UI theme adds the rest of junk on the outside.

    It's a major thing to fix, but better it were fixed sooner than later.

    Oddly enough, buttons (which often are done the way Windows are done in the Unity GUI) work like Windows in any other library.
     

    Attached Files:

  2. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    I discovered this issue this evening while testing Shaun's new skins. I was hoping that I could flip from skin to skin by just setting GUI.skin and was disappointed this wasn't the case.

    So do we file this in the "Wish List"?
     
  3. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    This was one of the things I was wondering the most about when designing the UnityGUI. Both seemed to break in some cases:

    With the current system, if you have two buttons next to each other and assign skins with huge padding values, the content will be clipped. This is not what you want

    If you add the sizes to the content, and have 2 buttons close to each other, assigning skins with larger margins can make them overlap - this is also not what you want.

    AFAICS, they would both be equally wrong. In the end, I did like Visual Basic, Cocoa, and CSS does it (yes, if you define a 10pixel-wide element and have a 2-pixel left padding, you will get an 8-pixel content area.

    If you want o be able to do this, you basically have 3 options:

    1) use GUILayout. There, the elements are modeled like the HTML box model, so buttons can push each other around.
    2) use GUIStyle.CalcScreenSize to calculate the screen size from the content size for a given style
    3) Use the overflow property to draw the background outside the area passed in.

    We cannot fix this now - fixing it (which I'm very convinced is actually NOT what you want) would break the existing GUIs out there, so no matter what we simply cannot do it.

    I hope some of the methods outlined above can help you accomplish what you want
     
  4. AaronC

    AaronC

    Joined:
    Mar 6, 2006
    Posts:
    3,552
    A lot, if not all the gui demos I've seen have overlapping text, which does not look good at all.

    Personally I'm waiting for some solid tutorial data before making the jump to 2.0. Theres no way I can make the jump till then. So this is also another vote for not depreciating the original gui system. Please leave it in?

    /2c
    AC
     
  5. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    I find the documentation to be pretty good and it's straightforward to use. At worst, I'd say that given the issues I'm discussing, you need to pick your skin (or at least your skin metrics) before you write your GUI code. This applies to the old GUI stuff so it's not really a disadvantage of the new GUI system versus the old, so much as a significant flaw in the new system.

    Might I add that the way buttons work in the GUI system is really bad too. Buttons need to be sized based on size not content, because they live INSIDE containers. Containers need to be based on content size not outer bound size because what lives in them needs to be able to fit.

    The GUI system has all this upside down, and as it is, you're not going to be able to change skin metrics once you've written your GUI code. This violates the entire stated philosophy of the skin system, which is to be like CSS.
     
  6. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    I think you can find a CSS attribute to support any design decision. And I'm pretty sure Cocoa and Classic do NOT do Windows this way. I'm certain that within a Window (even Visual Basic) coordinates are based on the content area, not the window's top-left corner.

    Here's the practical difference:

    I want to stick some things of known size into a window. To do it using the system as it is I need to interrogate the style to find out the internal metrics necessary to build out enough space to stick them inside.

    Oh, when I stick things in them, I need to offset them all by some calculated factor based on interrogating the style as well.

    In my world, I simply make the window the size I want and stick things exactly where I expect. Voila.

    It's what I want -- see above. How heavily invested are folks in the current system?

    Here's another option: provide a new variant of the window call that allows you to specify a Window from its interior space. Doesn't break a thing. Heck, I guess it's something I'll write myself.

    Even so, it won't fix the offset problem. If you guys did it then it could make the offset problem go away.

    Concrete Example

    I want to stick a text field that's 120x20 at 10,10 inside a 140x40 (interior space) window.

    Current system:
    Find out the window padding: L, T, R, B
    Make a Window that's 140 + L + R wide and 40 + T + B tall, and then place the control at 10 + L, 10 + T.

    Proposed system:
    Make a window 140x40
    Place control at 10,10.

    I'd suggest you simply overload the Window method to support the latter.
     
  7. shaun

    shaun

    Joined:
    Mar 23, 2007
    Posts:
    728
    I have to chime in here, in the defense of GUI2 ;)
    It's not as 'wrong' as it sounds. To be honest the dream of 'skin flipping' is entirely possible but you just need a little extra code to make it work. You also have to consider that complex skins systems are rarely plug'n'play - they are abstracted from your logic and therefore will need some modification to work. Moreover, real apps that allow you to skin-flip generally have super tight design guidelines. The Skins I designed didn't follow any guidelines set by Unity - in fact i specifically made them different to give some variety - we don't want all Unity GUI's to look like clones, do we?

    So, in my case, I have to support 7 languages including Chinese Japanese and Korean (which I've moaned about before on the forum) - and this forces me to push the GUI pretty hard. So, to be able to swap skins easily, I just configure certain defaults for each skin at runtime that relate to controls, and when users make the switch, between skin, or language (buttons with German text tend to be longer, Chinese shortest etc) I just make a change. I won't say that its simple, but it does work.

    The only things I would suggest changes to are possibly the window, as when we have large shadows (like the huge ones in Leopard) they still receive the click and activate. IMO Buttons need to be able to capture more events, I'm not a big fan of the "if(gui.button){}" idea, each control should have a reference that I can access like anything else (like winforms) - however, whats there now works until the next update.

    If you've tried doing GUI in other 3D engines, Unity is superior by a long shot - things like GUILayout just don't exist in anything the other guys are offering AFAIK. (except maybe Anark, but who uses that for real work)
     
  8. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    I think the main issue is that the coordinates of objects within a Window be relative to its content area and not the top left of the Window.

    Extremely different skins are not going to be "plug and play" but the amazing thing to me is that two themes that use the same font are dramatically incompatible because of, in essence, one design decision which (as I've outlined above) could be fixed without breaking existing code.

    And to Targos -- again -- I'm not saying that the new UI sucks and the old UI needs to be kept. Stick a fork in its ass :). I'm simply saying that the new UI could be even better with relatively minor changes. (Previously, I said major, but I came up with a cleverer solution...)

    I might add that I'd have been quite happy with the new GUI system if it weren't skinnable.
     
  9. CoherentInk

    CoherentInk

    Joined:
    Jul 16, 2006
    Posts:
    216
    To be honest, CSS is frequently less than perfect as rules are written for a very specific framework. You can't take the rules from one site and apply them to another without expecting to port things over-- either on the CSS side or the XHTML side. It's never easy.

    That said, have you worked much with the GUILayout system? I know it may not have the level of precision that you want, but it certainly would be flexible.
     
  10. nafonso

    nafonso

    Joined:
    Aug 10, 2006
    Posts:
    377
    I haven't really played around with the new GUI, I got sloppy and the trial ran out and I haven't still upgraded, however this concept of "if(gui.button)" is the one that makes me much less "confortable" with it.
    I think that this will make me have lots of variables just to keep track of things, probably I'll make my own classes which I will keep a reference for when I want more complex things, like an inventory system or a chat system.

    Regards,
    Afonso

    PS: Oh, and the other thing that will feel strange to me is no visual editor to create the GUIs, I've been using Netbeans for far too long, my non-visual GUI creation was in the time of GTK+ 1.x.
     
  11. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    It should be fairly easy to build a graphical layout tool in Unity itself.

    I don't particularly care for a lot of aspects of the GUI system. Essentially widgets aren't persistent (with a few kludges to do things like keep track of text selections in TextFields, but I suspect it only can track on TextField). But it does *do the job*.

    BlitzMax's GUI stuff is a lot more sophisticated; but its 3D library is about two years too late...
     
  12. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    One disadvantage of the new GUI system over the old is that you can't see the stuff you're working on unless the game engine is running... and you can't realistically change anything while it is running.

    Ultimately -- for non-trivial applications -- I guess one needs to write an abstraction layer on top of the new code that has a persistent internal data representation of the UI, does things like treat widgets as persistent objects, and allows you to edit the UI on the fly.

    This isn't a bad thing, it's just not as nice as, say, Visual Basic.
    Agreed. And I do think that there's a basic problem with:

    foo = GUI.TextField( .... )

    because a TextField has more internal state that its current string.

    And the way you assign names to widgets to allow you to set focus on them is horrible!
     
  13. shaun

    shaun

    Joined:
    Mar 23, 2007
    Posts:
    728
    You can use ExecuteInEditMode to have the GUI display in the editor.
    http://unity3d.com/support/documentation/ScriptReference/ExecuteInEditMode.html

    Regardless, I do most of my changes at runtime as I use a lot of scripted variables. It's pretty much the same.

    I agree that the GUI controls need to be more sophisticated - If i want to find out which control my mouse is over, or what state a button is in at a given frame, it's very tough right now.
     
  14. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    Oooh :) ExecuteInEditMode() -- thanks for that tip.

    I think, fundamentally, that Unity would be best served by a mechanism for handling 2d objects and graphics that was as good as its mechanism for handling 3d objects. A UI widget really ought to be a "first class citizen" of the Unity UI -- i.e. an object that appears in the hierarchy, can be dragged around, and have its attributes edited.

    That said, I'm not sure that it isn't possible to build such a thing (using ExecuteInEditMode() ;-) !?) with what we've been given.

    Again -- not saying Unity's UI sucks. Just that it's not the same level of awesomeness as most of the rest of the product.

    P.S.

    Is there even a mechanism for having disabled buttons? It looks like you need to build a GUIStyle just to override the appearance of your button to make a button appear to be disabled.
     
  15. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    Oh -- going back to my original whine (about window offsets) -- it looks like this isn't actually a problem if you calibrate margins / padding in the GUISkin correctly ... so it's a total non-issue.

    Edit: or is it? Sigh. :-/ I still can't figure out all the interactions of padding, margin, etc.

    Now back to the subsequent whining :-D