Search Unity

eDriven Q&A

Discussion in 'Assets and Asset Store' started by dkozar, Aug 22, 2012.

  1. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Guys, this forum thread became too huge, so I created the eDriven forum at the address:

    forum.edrivengui.com

    Please use it for asking questions!

    You can login to eDriven forum by creating an account or using Facebook:

    $facebook.png


    ------------------------------------------


    I created this thread to answer the questions regarding eDriven framework (I'd like to have the eDriven.Gui thread for news and updates only).



    Other threads covering eDriven.Gui:

    eDriven
    eDriven.Gui

    eDriven.Gui - GUI for programmers

     
    Last edited: Oct 15, 2013
  2. oddgoo

    oddgoo

    Joined:
    Nov 22, 2011
    Posts:
    12
    Just wanted to say, thank you for your answer! I'll be keeping a close look on the package.
     
  3. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,316
    The thing is, the UnityGUI category is for the actual Unity GUI system. I've moved this to Assets Asset Store, which is for third-party assets.

    --Eric
     
  4. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    You're right. Thanks.
     
  5. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Continuing from here: http://forum.unity3d.com/threads/143093-eDriven.Gui-GUI-for-programmers/page2

    This goes into the next build, you would then use this one-liner:

    Code (csharp):
    1. eDriven.Core.Framework.EnableInfoMessages = false;
     
    Last edited: Aug 23, 2012
  6. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Just some Unity warnings, I believe this has nothing to do with a framework.

    This works generally on each component type:
    Code (csharp):
    1. myCmp.KeyDownFilter = new List<KeyCode>(new[] { KeyCode.Return, KeyCode.Space });
    2. myCmp.KeyUpFilter = new List<KeyCode>(new[] { KeyCode.Return, KeyCode.Space });
    For TextField you also have:
    Code (csharp):
    1. myTextField.AlowedCharacters = "-0123456789"
     
  7. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Using this method overload, you could further customize alert buttons:
    Code (csharp):
    1. Alert.Show(
    2.     delegate(string action) // this is the callback
    3.     {
    4.         Debug.Log("The action was: " + action);
    5.     },
    6.     new AlertOption(AlertOptionType.HeaderIcon, ImageLoader.Instance.Load("Icons/lock")),
    7.     new AlertOption(AlertOptionType.Title, "Logging in"),
    8.     new AlertOption(AlertOptionType.Message, "Please sign out with your Facebook account to post comments.\n\nAlternatively, you could log in manually."),
    9.     new AlertOption(AlertOptionType.Button, new AlertButtonDescriptor("facebook", "Login with Facebook", Resources("Icons/facebook"), true)),
    10.     new AlertOption(AlertOptionType.Button, new AlertButtonDescriptor("manual", "Login", Resources.Load("Icons/key"))),
    11.     new AlertOption(AlertOptionType.Button, new AlertButtonDescriptor("cancel", "Cancel", Resources("Icons/cancel")))
    12. );
     
  8. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Nope. eDriven.Gui currently works on top of the immediate GUI, thus inheriting all of it's restrictions. You can style the TextField using the TextFieldStyleMapper, but only one font/color per text field:

     
  9. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
  10. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Use GetTabChildren() method of your Form (Container):

    Code (csharp):
    1. public override List<DisplayListMember> GetTabChildren()
    2. {
    3.     return new List<DisplayListMember> { _btnSubscribe, _btnFoo, _chkBar, _comboBaz };
    4. }
    Note: Each component has to be FocusEnabled = true.
     
  11. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    In eDriven there's no special window class - you can popup every component. For displaying popups you should use the PopupManager:
    Code (csharp):
    1. LoginDialog popup = new LoginDialog();
    2. PopupManager.Instance.AddPopup(loginDialog);
    To remove the popup use:
    Code (csharp):
    1. PopupManager.Instance.RemovePopup(popup);
    To communicate with popup use setters (properties accessible from outside) and callback functions:
    Code (csharp):
    1. LoginDialog loginDialog = new LoginDialog();
    2. {
    3.     Message = "Please login", // property
    4.     Callback = delegate(string loginAction) // callback
    5.     {
    6.         switch (loginAction)
    7.         {
    8.             case "success":
    9.                 Foo();
    10.                 break;
    11.         }
    12.     }
    13. };
    14. PopupManager.Instance.AddPopup(loginDialog);
    For dialogs you could use the Dialog class. It has a header (if Draggable = true), and exposed Tools, HeaderGroup and ButtonGroup containers (available immediatelly inside the InitializationComplete()).

    You can supply cour own buttons via ButtonGroup.AddChild. Your button could then trigger the ExecCallback method, which is a default callback (you can also supply other callbacks when overriding the dialog) and also removes the popup automatically.

    Code (csharp):
    1. public class MyCustomDialog : Dialog
    2. {
    3.     Button _btnClose;
    4.     Button _btnCancel;
    5.     Label _txtComp;
    6.    
    7.     protected override void InitializationComplete()
    8.     {
    9.         base.InitializationComplete();
    10.  
    11.         MinWidth = 200;
    12.         MinHeight = 200;
    13.         Width = 300;
    14.         Height = 400;
    15.  
    16.         Draggable = false;
    17.         Padding = 10;
    18.  
    19.         _btnClose = new Button { Icon = (Texture)Resources.Load("Icons/close_16"), Width = 20, Height = 20 };
    20.         _btnClose.Click += delegate { PopupManager.Instance.RemovePopup(this); };
    21.         Tools.AddChild(btnClose);
    22.  
    23.         ButtonGroup.Visible = ButtonGroup.IncludeInLayout = false; // we could even hide the button group
    24.     }
    25.    
    26.     protected override void CreateChildren()
    27.     {
    28.         base.CreateChildren();
    29.  
    30.         _txtComp = new TextField {PercentWidth = 100, MouseEnabled = true, Editable = false}; // allow cropping if too long
    31.         AddContentChild(_txtComp); // this goes into content
    32.  
    33.         _btnCancel = new Button
    34.         {
    35.             Text = "Close",
    36.             Icon = (Texture)Resources.Load("Icons/cancel")
    37.         };
    38.         _btnCancel.Press += delegate
    39.         {
    40.             ExecCallback(CANCEL);
    41.         };
    42.         ButtonGroup.AddChild(_btnCancel); // this goes into the button group
    43.     }
    44. }
     
  12. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    You got to listen for KEY_UP or KEY_DOWN event (depending of your choice) - but ONLY when component in focus. Here's the excerpt from the LoadImages demo:

    Code (csharp):
    1. _txtSearch = new TextField
    2.  {
    3.      Text = "croatian coast",
    4.      FocusEnabled = true,
    5.      Width = 400
    6.  };
    7. _txtSearch.SetFocus();
    8. _txtSearch.KeyUp += delegate (Event e)
    9. {
    10.     KeyboardEvent ke = (KeyboardEvent) e;
    11.     if (ke.KeyCode == KeyCode.Return)
    12.     {
    13.         Search();
    14.     }      
    15. };
    16. AddChild(_txtSearch);
    For Buttons, there is Button.PRESS event type, and correponding multicast delegate button.Press:

    Code (csharp):
    1. button.Press += delegate { Foo(); }
    Press is the aggregate of CLICK and KEY_UP, meaning when button in focus it can be pressed by the ENTER key.
     
  13. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    You are in the async world now.

    Show method cannot possibly return the result because it is not synchronous (i.e. the result of the method isn't known immediatelly, it has to wait for user's interaction).

    You have to use one of the Show() method overloads which supports supplying the callback function:
    Code (csharp):
    1. Alert.Show(
    2.     delegate(string action) // a callback
    3.     {
    4.         Foo(action);
    5.     },
    6.     new AlertOption(AlertOptionType.Title, "Info"),
    7.     new AlertOption(AlertOptionType.Message, "It's your choice."),
    8.     new AlertOption(AlertOptionType.Flags, AlertButtonFlag.Ok | AlertButtonFlag.Cancel)
    9. );
     
  14. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    TabNavigator question.

    Code (csharp):
    1. _nav = new TabNavigator
    2. {
    3.     PercentWidth = 100,
    4.     PercentHeight = 100,
    5.     VerticalSpacing = 4,
    6.     ButtonMinWidth = 40
    7. };
    8. AddContentChild(_nav);
    9.  
    10. _txtLayout = new TextField
    11. {
    12.     PercentWidth = 100,
    13.     PercentHeight = 100,
    14.     Editable = false,
    15.     Multiline = true,
    16.     ScrollContent = true,
    17.     AlwaysShowVerticalScrollbar = true,
    18.     NavigatorDescriptor = "Layout"
    19. };
    20. _nav.AddContentChild(_txtLayout);
    21.  
    22. _txtSpacing = new TextField
    23. {
    24.     PercentWidth = 100,
    25.     PercentHeight = 100,
    26.     Editable = false,
    27.     Multiline = true,
    28.     ScrollContent = true,
    29.     AlwaysShowVerticalScrollbar = true,
    30.     NavigatorDescriptor = "Spacing"
    31. };
    32. _nav.AddContentChild(_txtSpacing);
     
  15. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    You could use the LoadingMask:

    Code (csharp):
    1. int count = 0;
    2.  
    3. LoadingMask mask = new LoadingMask(btn1);
    4. mask.SetMessage(string.Format("Masking... {0} seconds", count));
    5.  
    6. Timer t = new Timer(1, 5);
    7. t.Tick += delegate
    8.             {
    9.                 count++;
    10.                 mask.SetMessage(string.Format("Masking... {0} seconds", count));
    11.             };
    12. t.Complete += delegate { mask.Unmask(); };
    13. t.Start();
     
  16. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Except skining the CheckBox (or Button with button.ToggleMode = true), nothing else out of the box.

    The answer could be: make a custom control.
     
  17. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Use AddField method to add any component. This means you can add the HBox containing a number of child components.

    Code (csharp):
    1. HBox hbox = new HBox();
    2.  
    3. TextField txt = new TextField { Width = 200; };
    4. hbox.AddChild(txt);
    5.  
    6. Button btn = new Button ();
    7. btn.Text = "Address book";
    8. hbox.AddChild(btn);
    9.  
    10. _form.AddField("dummy", "Composite control", hbox);
     
  18. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Use TileLayout and size the container so that it can have only 3 children in a row.

    The example is in LoadImages demo source (look for "_box" in LoadImages.cs)
     
  19. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    It's all 1.3, the DLL info has not been updated.
     
  20. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    KeyboardMapper is used to map keyboard events globally for the application. This feature is mostly used for player controls etc.
    If using KeyboardMapper - then your method is good, because you should use a flag.

    But there's another way to do it, an this is the primary way of doing things in eDriven:

    All components dispatch KeyboardEvents. However, it only happens if they the component has ProcessKeys = true and when this (single component at a time) is in focus.

    So you could subscribe to KeyUp multicast delegate (or AddListener(KeyboardEvent.KEY_UP) - which is the same).

    However, there are a convenience protected virtual methods in component class: KeyUpHandler and KeyDownHandler, that automatically subscribe/unsubscribe to keyboard events when in focus, so it is better to use these (when inside the component), just to leave them to take care of subscribing/unsubscribing. Internally, it works like this:

    Code (csharp):
    1. if (/* I am processing key events and I am in focus */)
    2. {
    3.     KeyDown += KeyDownHandler;
    4.     KeyUp += KeyUpHandler;
    5. }
    6. else
    7. {
    8.     KeyDown -= KeyDownHandler;
    9.     KeyUp -= KeyUpHandler;
    10. }
    So, listen to key events this way:

    Code (csharp):
    1. _txtSearch.KeyUp += delegate (Event e)
    2. {
    3.     KeyboardEvent ke = (KeyboardEvent) e;
    4.     if (ke.KeyCode == KeyCode.Return)
    5.     {
    6.         Search();
    7.     }
    8. }
     
    Last edited: Aug 24, 2012
  21. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Let me continue with the previous post.

    Since the Alert class closes itself (cancels) on KEY_UP, other components shouldn't react on this event since they are not in focus.

    In GUI programming, a number of actions has to be "done later".

    There are convenience methods for delaying actions in eDriven. One of them is the Defer method. This is the instance method of the component. If you have a piece of code that has to be done a few frames later, this is the way you use it:

    Code (csharp):
    1. Defer(delegate { Foo(); }, 1); // Foo() will run one frame later
    Normally, delays so short aren't noticeable.
     
    Last edited: Aug 24, 2012
  22. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Ah, you are not inside the component. If deferring from scripts, use:

    Code (csharp):
    1. DeferManager.Instance.Defer(delegate { Foo(); }, 3); // defer for 3 frames
     
  23. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Or, if Foo has the DeferManager.DelayedAction signature (which it has here):

    Code (csharp):
    1. DeferManager.Instance.Defer(Foo, 3); // defer for 3 frames
    And inside the Foo is everything you need to run after N frames:

    Code (csharp):
    1. private void Foo() {
    2.     Alert.Show(...)
    3. }
    Or directly via delegate:

    Code (csharp):
    1. DeferManager.Instance.Defer(delegate {
    2.     Alert.Show(...)
    3. }, 3); // defer for 3 frames
     
  24. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Of course :) To me this happens automatically. Sorry for assuming everybody's using Visual Studio (Express) or ReSharper. :)

    I prefer to be concise. Very nice of you for filling in the gaps -> fell free to do that ;)
     
  25. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Nope, as I remember this is where the underlying immediate TextField takes control.

    I just implemented the following static properties on Alert:
    Code (csharp):
    1. public static bool CircularTabs;
    2. public static bool CircularArrows;
    3. public static bool ArrowsEnabled = true;
    (will go into the next build)

    Implement GetTabChildren() as in one of the examples. With it, you can also define the order.
     
  26. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    The latter is written OK - it's all eDriven events (eDriven.Core.Events.Event)

    Actually I saw this warning once - in script - and cannot remember the reason. Try using the method reference instead of the delegate.

    I'm using Debug.Log() for debugging purposes (got a special debug build with #if DEBUG statements and writing interesting things to log only when in debug build).
     
  27. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    You have to chose a single layout for the container, and all of its children play by its rules.
    Or: you can turn the layout OFF for some children with: child.IncludeInLayout = false;
    Or: you could layer two containers on top of each other, each with a different layout.

    Btw. LayoutDescriptors are defaults made for quick prototyping, normally you should use the Layout property instead. Plug in any of the layouts (BoxLayout - this is both HBox and VBox), Absolute layout etc. and configure it in details.

    Place the control into a Container (or Stage) that has an AbsoluteLayout. Make it:

    Code (csharp):
    1. myControl.Width = 100;
    2. myControl.Right = 0;
     
    Last edited: Aug 26, 2012
  28. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Actually I can, because this is not the framework code, but a specific (script) implementation for my demos (attach).

    This is also the MVC example (or as I call it: "semi data-binding").
     

    Attached Files:

  29. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Nah, like it as it is.

    Will look at it.

    If I could split in 2, one of us would be fixing the Level bug, and the other one would answer your questions :)

    Didn't try it, but should work with Change event:

    Code (csharp):
    1. txt.Change += delegate (Event e) {
    2.     txt.Text = txt.Text.ToUpper();
    3. }
     
  30. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    No (for individual controls), that would break the layout rules, wouldn't it? Layout is how the parent places its children, not vice-versa.
     
  31. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    The solution for this error is found here. Basically you have to tweak the font importer.
     
  32. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Attach.
     

    Attached Files:

  33. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    There's a ScreenSize property in SystemManager which gives you the currrent screen dimensions.

    When placing the control inside a container, it won't be measured as long as the container doesn't run the measure pass. So, you cannot know the final size except if you give it the fixed size.

    However, there's a method to force validation passes on control which is not yet officially measured: you have to call myControl.ValidateNow() and after that you can read it's dimensions for further calculations.
     
  34. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    - eDriven.Core source: https://github.com/dkozar/eDriven
    - eDriven.Gui is not open source (as it was already said)
    - found the reason for a Level bug, will solve it in a day or two

    Cheers!
     
  35. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    This is a sporadic error (I saw it once, for me it works). When it happens, proceed as follows:

    Instead of this:

    Code (csharp):
    1. txt.Change += delegate (Event e) {
    2.     txt.Text = txt.Text.ToUpper();
    3. }
    write this:

    Code (csharp):
    1. txt.Change += new EventHandler(delegate (Event e) {
    2.     txt.Text = txt.Text.ToUpper();
    3. });
    4.  
    or this:

    Code (csharp):
    1. txt.Change += ChangeHandler;
    2.  
    3. private void ChangeHandler(Event e) {
    4.     txt.Text = txt.Text.ToUpper();
    5. }
     
  36. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Bugs fixed. Uploading a new version to the AssetStore tonight. Will post a message when visible online (probably tomorrow).
     
  37. holyjewsus

    holyjewsus

    Joined:
    Mar 7, 2011
    Posts:
    624
    Hey dkozar, are you going to do any examples/tutorial videos for the edriven framework like you have for the GUI? I'm very interested in learning about software development practices outside of unity, and this seems like a great way.
     
  38. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    I'd really like to, but never having enough time for eDriven.Core, since promoting GUI :|

    However, there are great resources for figuring out how it works:

    1) GitHub repository: https://github.com/dkozar/eDriven

    2) Sources of eDriven.Gui demos, which also contain Core classes. For example, the Twitter demo shows how to connect asynchronously to a server as well as the usage of other core classes. Source here: http://edrivenunity.com/backend/source/load-images-source/
     
  39. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    A small demo I made yesterday (loading different scenes...): http://edrivenunity.com/unity/load_level/
     
  40. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Set this up before any of eDriven managers gets called, for instance:
    Code (csharp):
    1. void Awake()
    2. {
    3.     eDriven.Core.Framework.EnableInfoMessages = false;
    4. }
    Try using only 1 default font per project, and let the other be named fonts.

    Furthermore you could style each component instance using the same style names a mapper property names, starting with small uppercase letter:

    Code (csharp):
    1. Label lbl = new Label { Text = "Styled label" };
    2. lbl.SetStyle("labelStyle", myGUIStyle);
    Will look into it.
     
    Last edited: Aug 31, 2012
  41. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    1. changes focus indicator globally (bluish rectangle around focusable controls)
    2. guess I should make one for tooltips too
     
  42. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Now I remember: check if cou have multiple unityengine.dll-s referenced within the editor. That is, the editor references one already, so you should remove the one in your project.
     
  43. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    When getting invalid casts, try using floats instead of integers:

    Code (csharp):
    1. hboxD.Width = Screen.width - 100f;
     
  44. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    1. They actually already do: both ENTER and SPACE. Check out the http://edrivenunity.com site.

    2. PopupManagerStage is a stage (singleton) to which all popups are being added by default. You should listen to CHILD_ADDED event, and if a child added is of AlertInstance type, you do the modifications. I'll cover this soon.
     
  45. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
  46. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Even better solution iwould be to subscribe to PopupManager, which dispatches the following events:



    That is because when listening to container's CHILD_ADDED event, you get an AlertInstance only when popup is non-modal, but a container holding both AlertInstance and ModalOverlay if modal.

    You have to subscribe once in the application:



    Now you got to check if this is an AlertInstance popped-up:



    You can explore Alert children by activating the sticky mode. You do this by Control-clicking the desired component. You can then walk the hierarchy using CTRL + arrows. Whis way you can reach even the children not dispatching mouse events (labels etc.)

    Left + right go UP and DOWN the hierarchy, LEFT and RIGHT go through siblings. ESC key or CTRL-clicking the currently sticky component terminates the sticky mode.



    Now, since AlertInstance inherits Dialog, you have all important containers exposed: HeaderGroup, ButtonGroup, ContentGroup, Tools.

    You can now reorder the children of these containers, hide them, change their layout etc. If you want to re-measure after changes, call ValidateNow().
     
  47. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    These are 2 ways of doing the same thing. The second internally translates to the first notation:
    Code (csharp):
    1. combo.AddEventListener(IndexChangeEvent.SELECTED_INDEX_CHANGED, delegate (Event e)
    2. {
    3.     IndexChangeEvent ice = (IndexChangeEvent)e;
    4.     Debug.Log("Index changed from " + ice.OldIndex + " to " + ice.Index);
    5. });
    Code (csharp):
    1. combo.SelectedIndexChangedHandler += delegate(Event e)
    2. {
    3.     IndexChangeEvent ice = (IndexChangeEvent)e;
    4.     Debug.Log("Index changed from " + ice.OldIndex + " to " + ice.Index);
    5. };
    Tag? Just the place to stick the stuff in? Every component has Data (object): put anything you want in it. It is even inspectable if using the details window ("Data" tab).

    Code (csharp):
    1. component.HighlightOnFocus = false;
    For DialogStyleMapper, please take a look at this image:



    Style mappers follow the hierarchy of components: since Dialog extends Panel, it will have all of its styles, plus its own (button styles).

    In this image you have a button group highlighted. All the styles beginning with "ButtonGroup" are related to that area. Same for "Header.." and "Content..". Every panel can also have an overlay (with each you for instance add the rectangle that is being drawn on top of all child controls). This isn't the disabled overlay, but a convenience thing with which you can add, for instance, the glossy effect to your panel.

    If you meant the disabled overlay, you set:
    Code (csharp):
    1. component.Enabled = false;
    If you meant the ModalOverlay, than you have to call:

    Code (csharp):
    1. PopupManager.Instance.AddPopup(myPopup, true); // true for modal overlay
    There are modal dialogs in project demos, so check out form demos 1 2.

    Not yet, but thinking about implementing it for a long time: it will be part of Core and extendable with gestures.

    Useful tip: There's a new property: CursorManager.Enabled (true by default). With it you could turn off cursor management completely (useful for mobile).

    Thought they are just for keyboard, but looking at this list, seems they are for joystick too.. :)

    http://docs.unity3d.com/Documentation/ScriptReference/KeyCode.html

    Just try it and report back ;)

    Like a composite control? Sure... In demos probably. Send me the details.

    Huh!? Never heard of it.

    :) Just remove line 14. What you did is you gave the explicit height to the list, and there's not enough items to cover that space. Before after:



    Cheers!
     
    Last edited: Oct 1, 2012
  48. Techdread

    Techdread

    Joined:
    Sep 10, 2010
    Posts:
    25
    Hi Dkozar,

    Just bought your GUI solution and now testing it.

    How do I set the Layout for containers?

    I tried this but its not working, the buttons are aligned to the left of the panel there is no vertical spacing. It loads up the level demo's OK. :)

    Code (csharp):
    1. protected override void OnStart()
    2.     {
    3.         base.OnStart();
    4.         LayoutDescriptor = eDriven.Gui.Layout.LayoutDescriptor.VerticalMiddleCenter;
    5.     }
    6.  
    7.     protected override void CreateChildren()
    8.     {
    9.         base.CreateChildren();
    10.  
    11.         mPanelMainMenu = new Panel{
    12.             Title = "Main Menu",
    13.             Layout = new BoxLayout {    Direction = LayoutDirection.Vertical,
    14.                                         HorizontalAlign = HorizontalAlign.Center,
    15.                                         VerticalSpacing = 20.0f}
    16.         };
    17.        
    18.         AddChild(mPanelMainMenu); //Attach Panel to screen
    19.         CreateMainPanelButton(mButtonAbsoluteLayout, "Absoloute Layout", 1);
    20.         CreateMainPanelButton(mButtonAddChild, "Add Child", 2);
    21.         CreateMainPanelButton(mButtonAddChild, "Auto Layout", 3);
    22.     }
    23.  
    24.     /// <summary>
    25.     /// Create Button for Demos attach it to a panel and add the Level to Load.
    26.     /// </summary>
    27.     private void CreateMainPanelButton(Button button, string buttonText, int levelToLoad)
    28.     {
    29.         button = new Button
    30.         {
    31.             Text = buttonText,
    32.             Icon = (Texture) Resources.Load("Icons/star") // should cache
    33.         };
    34.         mPanelMainMenu.AddChild(button);
    35.         button.Click += delegate { Application.LoadLevel(levelToLoad); };
    36.     }
    37. }
    Speaking from the little I have tried of your Framework your a genius.:cool:
     
  49. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Oh, thank you, you're too kind :)

    The problem with your code is this: when adding children to Panel and its derived classes (Dialog etc.) you have to use AddContentChild method, rather than AddChild.

    That is because the panel has 2 children: HeaderGroup and ContentGroup. AddContentChild adds children to ContentGroup.

    You might ask why didn't I override the AddChild in panel to add children to ContentGroup directly? That is because I wanted to keep the AddChild functionality so the developer could add more children to panel itself (just like you did unintentionally).

    This is the first child of the panel (HeaderGroup):



    This is the second child of the panel (ContentGroup, has height of 0px since no children inside to size it):



    This is where AddChild added your first button:



    This is where AddContentChild adds your first button:



    Finally, you should add Padding=10 to your panel, and you get:



    Here is the full source:

    Code (csharp):
    1. using eDriven.Gui.Components;
    2. using eDriven.Gui.Containers;
    3. using eDriven.Gui.Layout;
    4. using UnityEngine;
    5. using Gui = eDriven.Gui.Gui;
    6.  
    7. public class MainMenu : Gui
    8. {
    9.     private Panel _panelMainMenu;
    10.  
    11.     protected override void OnStart()
    12.     {
    13.         base.OnStart();
    14.         LayoutDescriptor = eDriven.Gui.Layout.LayoutDescriptor.VerticalMiddleCenter;
    15.     }
    16.  
    17.     protected override void CreateChildren()
    18.     {
    19.         base.CreateChildren();
    20.  
    21.         _panelMainMenu = new Panel {
    22.                                        Title = "Main Menu",
    23.                                        Padding = 10, // padding added here
    24.                                        Layout = new BoxLayout {
    25.                                                                   Direction = LayoutDirection.Vertical,
    26.                                                                   HorizontalAlign = HorizontalAlign.Center,
    27.                                                                   VerticalSpacing = 20
    28.                                                               }
    29.                                    };
    30.  
    31.         AddChild(_panelMainMenu); //Attach Panel to screen
    32.         CreateMainPanelButton("Absoloute Layout", 1);
    33.         CreateMainPanelButton("Add Child", 2);
    34.         CreateMainPanelButton("Auto Layout", 3);
    35.     }
    36.  
    37.  
    38.  
    39.     /// <summary>
    40.     /// Create Button for Demos attach it to a panel and add the Level to Load.
    41.     /// </summary>
    42.     private void CreateMainPanelButton(string buttonText, int levelToLoad)
    43.     {
    44.         Button button = new Button
    45.                             {
    46.                                 Text = buttonText,
    47.                                 Icon = (Texture) Resources.Load("Icons/star") // should cache
    48.                             };
    49.  
    50.         _panelMainMenu.AddContentChild(button); // add as content child!
    51.         button.Click += delegate { Application.LoadLevel(levelToLoad); };
    52.     }
    53. }
     
  50. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Yes, I'll definitely do that. Meanwhile, you could use a label of your choice, just pop it up this way:

    Code (csharp):
    1. Label _yourTooltip = new Label {Text = _yourTooltipText}
    2. PopupManager.Instance.AddPopup(_yourTooltip , new PopupOption(PopupOptionType.Stage, TooltipManagerStage.Instance));
    This should make the label to be displayed at a tooltip depth.

    You could remove it later this way:
    Code (csharp):
    1. PopupManager.Instance.RemovePopup(_yourTooltip ));
     
    Last edited: Nov 3, 2012
unityunity