Search Unity

eDriven Q&A

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

  1. tomshreds

    tomshreds

    Joined:
    Feb 25, 2013
    Posts:
    32
    I'm having lots of these errors:
    !dest.m_MultiFrameGUIState.m_NamedKeyControlList

    Without any source so I was wondering if it was related to eDriven.Gui?

    Any update about the StyleMapper article? (no rush)

    Thanks!
     
  2. dkozar

    dkozar

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

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Not related to eDriven. :)
     
  4. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    You should first read the part on using StyleMappers in the manual.

    More than year ago, I was thinking about the styling system that's using "original" Unity styles, but that won't break if any of the styles missing (which was usually the case). :)

    I wanted the ability to style my components using the GUISkins and GUIStyles, but having a fallback if the styles are not present.



    Please note that my system of styling is a pretty complex system for component builders, but (hopefully) easy one for component users.

    This is how it works:

    We have a component that we want to be styleable (Button in this example).



    Note that it's decorated by an attribute indicating the type of a the style proxy that styles will be loaded from:

    Code (csharp):
    1. [StyleProxy(typeof(ButtonStyleProxy))]
    It is also decorated with aditional attributes indicating the style name declaration (having a type and proxy property name):

    Code (csharp):
    1. [Style(Name = "buttonStyle", Type = typeof(GUIStyle), ProxyPropertyName = "ButtonStyle")]
    Now let's explain the style proxy. A proxy is the singleton so will be retrieved only once (at the scene start). Each proxy extends StyleProxyBase - a class receiving two type parameters in its class definition:


    1. The first type (ProxyInstance) is instantiated if StyleMapper not present (it contains the hardcoded styles).
    2. The second type (StyleMapper) is the actual style mapper type that will be looked upon the application start in the scene and styles will eventually be retrieved from it
    Since the first class (ProxyInstance) is pretty short, I usually keep it within the same (proxy) file.

    Here's the style mapper class:



    This is actually a script that can be retrieved from Unity menu and attached to a game object.

    Important: note that both the proxy and the mapper class both extend the superclass, the same way the component extends it.

    This is a parallel hierarchy system with 3 parallel hierarchies!

    What's left to do is to implement the StyleChanged method of a component.



    This method is being called by the system when a certain style is ready (is retrieved from the style mapper or is a hardcoded one).

    This method is also called when you call the SetStyle method from code.

    What you have to do is to implement this method and switch..case through styles the component is interested in. You could retrieve each style using the GetStyle method:

    Code (csharp):
    1. var myStyle = (GUIStyle)GetStyle("buttonStyle");
    The Button class saves the style (reference) into a variable named ActiveStyle - which is then used when rendering the button.

    I'm attaching a few more example screenshots (the Dialog class, its style proxy and style mapper) hoping it will make a bit clearer how this stuff works. :cool:
     

    Attached Files:

    Last edited: Mar 28, 2013
  5. Laurie-Athey349

    Laurie-Athey349

    Joined:
    Jan 28, 2013
    Posts:
    14
    Using the free version and fixed a few errors to get it running but one devious son of a... nvm, here is the error:

    Internal compiler error. See the console log for more information. output was:
    Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'eDriven.Core, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies.

    File name: 'eDriven.Core, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null'

    No idea what that means and thats like 1/20th of the error.

    Anyone know what it means?
     
  6. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Seems like your eDriven.Core.dll is somehow missing. Please try to reimport all the items from the project.
     
  7. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    With eDriven.Gui v1.10, style mapper bugs are being solved.

    On each the scene change, all the StyleProxies are being destroyed (by default). New definitions are then loaded from style mappers found in the new scene.

    This solves the strange artifacts of "ghost" styles on scene change.

    Also, the v1.10 introduces an additional StyleMapper parameter - Persistent:



    When the style mapper is persistent, the style proxy to which his styles are loaded will not be destroyed on scene change. This means that proxies (containing GUIStyles used by the system) created in the first scene could be reused throughout the scenes (levels) during the application lifetime.

    However, the default value of Persistent parameter is false (check box is being switched OFF). This is because my guess is that this makes the better and more logical default.

    For illustration on how this system works, let's look at the first scene:



    The mapper in the first image is present in this scene, and list controls are actually being rendered using this mapper.

    The other scene is being loaded without a such mapper present. But since referencing the same mapper ID (using list.StyleMapper = "listBig" and the "listBig" mapper is persistent and not destroyed on scene change) - the new list is reusing it:



    When debugging, I could even see which of the previous scenes instantiated this persistent proxy:



    So, eDriven is getting more robust and predictable. :)

    eDriven.Gui v1.10 will be uploaded to the Asset Store in a few days. :)

    Danko
     
  8. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    eDriven.Gui 1.10 is now available in the Asset Store.

    Please download the latest version:
    • Multiple bug fixes
    • Fixed bug causing "ghost" styles on scene change
    • Now all the style proxies are being destroyed on scene change (default behaviour)
    • Additional style mapper option for persisting (caching) particular styles throughout multiple scenes
    • Application.isGenuine check is now removed
    • Drag drop proxy position problem fixed
    • Problems related to TextField focus fixed
    • 2 new demos added:
      - drag&drop demo 2 ("inventory demo", example usage of a custom drag proxy)
      - console demo (custom eDriven component with internal logic and source code)
    You might wanna try before you buy.

    Danko :)
     
  9. Laurie-Athey349

    Laurie-Athey349

    Joined:
    Jan 28, 2013
    Posts:
    14
    Hey,

    I get the following error when I try to draw a button.
    "
    Exception: Default font mapper not defined
    eDriven.Gui.Mappers.FontMapper.GetDefault ()
    A.cfe017892a55333e37bb3b2950bd14122.cf4f38ddf83d0af566f158f9b2a1ae9b0 ()
    A.cfe017892a55333e37bb3b2950bd14122.c45a4ecb5f7e90d151c4f9c1673b47e1f ()
    Acme.caaf318fd8fd78b5d6c453dc827148bc2 ()
    Acme.Start ()
    "

    And the button doesnt draw just an eDriven.Gui disclaimer that floats around the screen.
    I followed the helloworld tutorial to the letter but thats all I get.
     
  10. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    When using eDriven.Gui, the default font mapper must be present on screen. It maps to the font that all eDriven components will use (for measuring and rendering) if not defined otherwise.

    Now, in "Hello world" tutorial I lied a bit: before I started to record, I already placed the font mapper to the scene, made it a default one and referenced a font. You might see it at 00:20.

    Another user made the Hello World workflow, so you might look at it. This should clearly go into the manual.

    Also note, there's a much easier way of working with eDriven.Gui - that is: starting from one of the available demos and deleting the stuff you don't need. :)

    Additional notes: while developing eDriven.Gui from "code" (using C#), you need no eDriven.Gui window in the editor (this is only for using the designer components).

    If you have it on screen, just turn off the "Inspect" toggle button. Because when over the game window, he might want to draw some overlays, and you're missing the font mapper.
     
  11. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    eDriven.Gui quarterly sale: only 24 hours left!!!

    Get it with 30% OFF - only $175! :)


    ~~~ Announcement ~~~

    Decided to do 30% OFF sales quarterly (at the end of each quarter: March, June, September, December).

    Leaving the possibility of 50% OFF exclusively to Asset Store Madness Sales (of course, if and when they decide to include the package).

    Danko
     
  12. tomshreds

    tomshreds

    Joined:
    Feb 25, 2013
    Posts:
    32
    Thanks a lot for this!

    I started testing and I have some more questions about StyleMappers:

    1) In your example, Button.cs is not needed since I just want to alterate the style of an already existing component (Button) right?

    2) So I would only need to create a StyleProxy and a StyleMapper right?

    3) Do I need to use the same namespace as the component I want to alter?

    Here's what I came up with so far:

    Code (csharp):
    1.  
    2. namespace eDriven.Gui.Mappers.Styles.Button {
    3.  
    4.     // Proxy
    5.     public class ButtonStyleProxy : StyleProxyBase<ProxyInstance, ButtonStyleMapper> {
    6.  
    7.         // Singleton
    8.         private static ButtonStyleProxy instance;
    9.  
    10.         public static ButtonStyleProxy Instance {
    11.             get {
    12.                 if (instance == null) {
    13.                     new ButtonStyleProxy();
    14.                 }
    15.      
    16.                 return instance;
    17.             }
    18.         }
    19.  
    20.     }
    21.  
    22.     // Mapper
    23.     [AddComponentMenu("eDriven/Gui/Styles/ButtonStyleMapper")]
    24.  
    25.     public class ButtonStyleMapper : ComponentStyleMapper {
    26.         [GUIStyleReference]
    27.         public StyleReference ButtonStyle;
    28.  
    29.         protected override void StyleChanged(string styleName) {
    30.             base.StyleChanged(styleName);
    31.  
    32.             switch (styleName) {
    33.                 case "buttonStyle":
    34.                     ActiveStyle = (GUIStyle)GetStyle("buttonStyle");
    35.                     ActiveStyle.padding = RectOffset(0, 0, 0, 0);
    36.                     break;
    37.             }
    38.         }
    39.     }
    40.  
    41. }
    42.  
    I guess it's not right since I get this:

    error CS0115: `eDriven.Gui.Mappers.Styles.Button.ButtonStyleMapper.StyleChanged(string)' is marked as an override but no suitable method found to override

    Could you please point me in the right direction? I believe I understood the whole concept well, but there's just part I'm unsure of.

    Thanks for the help as always!
     
    Last edited: Mar 31, 2013
  13. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    If you are NOT developing your custom components FROM THE CODE you DO NOT NEED to create style mappers or do any other type of coding.

    If you want to style ANY TYPE OF BUTTON (code or designer) you need to put a button style mapper in the scene (pick it from eDriven component menu). Give it an ID and use this ID with your component.

    StyleChanged is a method override of Component class - not of the proxy or mapper classes.
     
    Last edited: Mar 31, 2013
  14. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Starting from v1.11, ProxyInstance class(es) will be renamed to DefaultStyles.

    The ProxyInstance name was a bit misleading - the proxy object is the singleton object (per control type) and this is the actual proxy instance.

    So it style proxies will be defined like:

    Code (csharp):
    1. /// <summary>
    2. /// My component style proxy
    3. /// Type parameters:
    4. /// 1. the type of default styles instance
    5. /// 2. the type of style mapper to be loaded
    6. /// </summary>
    7. MyComponentStyleProxy : StyleProxyBase<MyComponentDefaultStyles, MyComponentStyleMapper>
    Each control class knows it's own proxy type it has to point to.

    The order of style loading is then:

    1. Component is trying to find the style mapper of the specified type in the scene (MyComponentStyleMapper)
    2. If it cannot find it, it falls back to creating the default styles instance instead (MyComponentDefaultStyles)

    This is of course true for destroyed proxies only. If proxy persisted from the previous scene, it won't be loaded again.




     
  15. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Just fixed this bug: the fix will be included with eDriven.Gui v1.11.

    It will work like this: while editing GUI (in designer), only the 1st scene changes will be persisted and offered for saving. So, if 2nd level loaded dynamically, its changes won't be persisted and won't mess with the 1st scene.

    Cheers!
     
  16. tomshreds

    tomshreds

    Joined:
    Feb 25, 2013
    Posts:
    32
    Thanks again, I now understand how the inner works but I have still one little question to get it all glued into my head properly:

    Once I added the ButtonStyleMapper component to my scene (btw can I add it on the button itself?) where do I need to tweak the padding (0, 0, 0, 0) and ImagePosition = ImageOnly?

    I looked up the docs about GUIStyle and found a lot of useful info then I created a new GUISkin with a custom style in it, but when I try to select it as the Skin (from the ButtonStyleMapper) it just doesn't show up. There must be some step missing. I'll try to look more about GUISkin/GUIStyle so I can understand how it works better.

    Thanks a lot again and have a nice day.
     
  17. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    That's right, you should add an instance of the style mapper to your scene. In it, you should reference your GUISkin file as "overal skin". And then, you have to set the style name by spelling it's name as "buttonStyle". This could be 'button', 'box', 'YourCustomStyleName' etc.

    You could add the mapper to your button, but this would look dirty since mappers are to be used by multiple components.
     
  18. tomshreds

    tomshreds

    Joined:
    Feb 25, 2013
    Posts:
    32
    Thanks for your answer, very helpful.

    I think I might have found a bug or maybe it's supposed to be like that in development builds I don't know.

    I tried a development build on a Windows 7 64bit on my girlfriend's Alienware laptop with a dedicated video card. And all of eDriven.Gui stuff looked semi-transparent and dialog had a layer of blue over them please look:


    Any idea of what's going on?

    Thanks!
     
  19. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Yeah, that's the "compromised quality" thing mentioned in the manual. You should set your quality to "fast" or more (now it's on fastest I guess).
     
  20. ParkerMan

    ParkerMan

    Joined:
    Mar 26, 2013
    Posts:
    11
    I am trying to do a login using your samples.

    Code (csharp):
    1.  
    2.  
    3.     public void ClickHandler(Event e)
    4.     {
    5.         if (e.Type.Equals("click")  e.CurrentTarget.ToString().Contains("textField")
    6.   e.Target.ToString().Equals("eDriven.Gui.Components.Button"))
    7.         {
    8.             Login logGui = (Login)e.CurrentTarget;
    9.  
    10.             string username = logGui.Username;
    11.             string password = logGui.Password;
    12.             Debug.Log(username + " " + password);
    13.         }
    14.     }
    15.  
    16.  
    My screen looks like... When I type username/password and hit submit, they are both blank.

    $4-2-2013 2-52-58 PM.png
    $4-2-2013 2-57-31 PM.png
     
    Last edited: Apr 2, 2013
  21. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    What you have to do is to subscribe to the "login" event:

    1. Create the event handler script (attach):

    $04a.png

    2. In edit mode, drag the script to your login control game object:

    $05.png

    3. In "Events" tab, map the "login" event to "LoginHandler" method in the script:

    $06.png

    4. Set "Send Mode" option of your LoginControl to "Dispatch Event":

    $04.png

    This should now work.

    Login control dispatches its own type of event when logging in. You don't have to listen to any click events, because these are low-level type of events that should be handled by the login control. You are interested in login event, which is an object already holding the valus of login and password, so you don't need to reference the username and password field from the outside.
     

    Attached Files:

  22. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    If you peek into the Login.cs script (eDriven.Extensions.Login.Login class) you'll actually see what the login control does: when submit button clicked, it builds the LoginEvent and fills in the username and password.

    This event is then being dispatched, so you can catch it from the outside world, if subscribed to LoginEvent.LOGIN constant, which is having the value of "login" (string).

    Furthermore, the login control sets the bubbling of the event to "true", meaning you can attach the event handler script to any of the login control ancestors (in the hierarchy) and process the event from there!

    $02.png

    $03.png
     
  23. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Hey, you were completely right! :) There was a bug in the control class (2 lines missing):

    $08.png

    These are of course mandatory to set text field values to LoginControl's Username and Password properties, both readable by the outside and used by the control when building the event. Now you get in the console:

    $07.png

    The fixed Login class in the attach.

    Cheers! ;)
     

    Attached Files:

  24. tomshreds

    tomshreds

    Joined:
    Feb 25, 2013
    Posts:
    32
    Thanks, that fixed the problem!

    I'm currently doing a list of names. I'm filling that list that way:
    Code (csharp):
    1.  
    2.     public void FillList() {
    3.         List list = GuiLookup.GetComponent("EmployeeList") as List;
    4.  
    5.         System.Collections.Generic.List<Profile> profiles = EmployeeManager.Instance.GetProfiles();
    6.  
    7.         foreach(Profile profile in profiles) {
    8.             list.DataProvider.Add(new ListItem(profile, profile.Name.ToString()));
    9.         }
    10.     }
    11.  
    It works fine but for some reason only the first item is selectable, the other are all greyed out. You can see an example here:



    Any idea of why this would happen? I checked in the inspector settings for the list and found nothing really relevant to some disabled state.

    EDIT: I don't know if this has been reported but on Mac OS X 10.8.2 when I launch the game and put it on my secondary monitor no eDriven.Gui stuff works at all. I cannot click on nothing and if I drag it back to the primary monitor it works fine.

    Thanks!
     
    Last edited: Apr 4, 2013
  25. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Hi, I'll check it out ASAP.
     
  26. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
  27. ScrappyRMH

    ScrappyRMH

    Joined:
    Apr 11, 2011
    Posts:
    48
    1. I have a ComboBox on a toolbar. It drops down the list and I select an item. But it is also allowing the click event to pass through to a game object behind the dropped down list. Is there some way to block that?

    2. On that same ComboBox (created in Designer) i assigned an event "close" to call a function. Whenever I select an item from the dropdown, or click the arrow to just cancel the selection, it calls the function twice. This is the only event assigned. Is this a bug? I expect it to only fire the event once.
     
    Last edited: Apr 4, 2013
  28. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Hi, I'll check it out ASAP. I probably forgot to cancel out the click event so it propagates to other items in the (popup manager) stage.

    Will look at it. There are also other useful events as I remember (try with 'change', 'changed', 'select'.. one of those).
     
  29. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Ah, I just figured out what the question really was. :)

    You are asking how to disable mouse events in a 3D world if the event has already been consumed by GUI.

    This question has already being answered in this thread. But I'll repeat the answer here.

    eDriven.Gui uses a system of flags being refreshed each time the mouse moves. These flags are then being set to reference the mouse-overed component:

    Code (csharp):
    1. // component under the mouse:
    2. MouseEventDispatcher.Instance.MouseTarget
    3.  
    4. // component under the mouse that will react on mouse wheel:
    5. MouseEventDispatcher.Instance.MouseWheelTarget
    6.  
    7. // currently focused component (received key input):
    8. FocusManager.Instance.FocusedComponent
    So, in your "3D code" you should just examine the MouseEventDispatcher.Instance.MouseTarget flag, and if not null you should not react to mouse clicks. It's that easy.

    It's the same for the focused GUI component (processing key input). If not null, you should block the keystrokes processing in your 3D code.

    Code (csharp):
    1. // script attached to a 3D game object
    2. using eDriven.Gui;
    3. using UnityEngine;
    4.  
    5. public class Demo : MonoBehaviour {
    6.     void OnMouseDown () {
    7.         if (MouseEventDispatcher.Instance.MouseTarget == null) {
    8.             // GUI not under the mouse. Do stuff with a game object.
    9.         }
    10.     }
    11.     void Update () {
    12.         if (Input.GetKeyDown ("space")  FocusManager.Instance.FocusedComponent == null) {
    13.             print ("space key was pressed");
    14.             // GUI not focused. Do stuff with a game object.
    15.         }
    16.     }
    17. }
     
  30. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    However, I just found that these flags are hard to find.

    So from v1.12 I will expose them statically through the Gui class:

    Code (csharp):
    1. /**
    2.  * Available in eDriven.Gui.Gui class (starting from eDriven.Gui v.1.12)
    3.  */
    4.  
    5. // <summary>
    6. /// The reference to a component that is under the mouse
    7. /// This component is looked upon after each mouse move on all stages
    8. /// </summary>
    9. public static Component MouseTarget;
    10.  
    11. // <summary>
    12. /// The reference to a component that will receive mouse wheel events
    13. /// This component is looked upon after each mouse move on all stages
    14. /// </summary>
    15. public static Component MouseWheelTarget;
    16.  
    17. // <summary>
    18. /// The reference to a component that is mouse-downed
    19. /// </summary>
    20. public static Component MouseDownComponent;
    21.  
    22. // <summary>
    23. /// The reference to the focused component
    24. /// </summary>
    25. public static Component FocusedComponent;
    So, your 3D code would look like this:

    Code (csharp):
    1. // script attached to a 3D game object
    2. using eDriven.Gui;
    3. using UnityEngine;
    4.  
    5. public class Demo : MonoBehaviour {
    6.     void OnMouseDown () {
    7.         if (Gui.MouseTarget == null) {
    8.             // GUI not under the mouse. Do stuff with a game object.
    9.         }
    10.     }
    11.     void Update () {
    12.         if (Input.GetKeyDown("space")  Gui.FocusedComponent == null) {
    13.             print ("space key was pressed");
    14.             // GUI not focused. Do stuff with a game object.
    15.         }
    16.     }
    17. }
     
  31. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    I'm examining it. Meanwhile, the combo box dispatches these types of events (strings + constants here):

    "opening" (ComboBox.OPENING)
    "open" (ComboBox.OPEN)
    "closing" (ComboBox.CLOSING)
    "close" (ComboBox.CLOSE)
    "selectedIndexChanged" (IndexChangeEvent.SELECTED_INDEX_CHANGED)

    So you could try to map these strings in the Events panel.
    • If canceling the event you get on "opening", combo box will stay closed.
    • If canceling the event you get on "closing", combo box will stay open.
    So, you have the control of opening/closing the combo box.
     
  32. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Additionally, I solved 2 combobox bugs:

    1. Due to me forgetting to internally cancel the mousedown event, this was happening (sporadically):



    A single line of code solved this problem:
    Code (csharp):
    1. private void MouseDownHandler(Event e)
    2. {
    3.     e.CancelAndStopPropagation(); // added line (fixes the propagation bug)
    4.     // open combobox...
    5. }
    2. Also, the combobox had problems with selection by clicking it in the game view. Now it works properly:

     
  33. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    I made some tests. This is my testing script:

    Code (csharp):
    1. using eDriven.Core.Data.Collections;
    2. using eDriven.Gui.Components;
    3. using UnityEngine;
    4. using Component=eDriven.Gui.Components.Component;
    5.  
    6. public class ListFiller : MonoBehaviour {
    7.  
    8.     void ComponentInstantiated(Component component)
    9.     {
    10.         // don't do it from from here, because DataProvider has not yet been initialized
    11.         //FillList((List)component);
    12.     }
    13.  
    14.     void InitializeComponent(Component component)
    15.     {
    16.         FillList((List)component);
    17.     }
    18.  
    19.     public void FillList(List list)
    20.     {
    21.         list.DataProvider.Add(new ListItem(1, "One"));
    22.         list.DataProvider.Add(new ListItem(2, "Two"));
    23.         list.DataProvider.Add(new ListItem(3, "Three"));
    24.     }
    25. }
    Indeed, when filling the list this way, the items are appended to the data provider, but are unelectable! I should fix this.

    However, setting the data provider works, so use this in the meantime.

    It could be done from both ComponentInstantiated and InitializeComponent:

    Code (csharp):
    1. using eDriven.Core.Data.Collections;
    2. using eDriven.Gui.Components;
    3. using UnityEngine;
    4. using Component=eDriven.Gui.Components.Component;
    5.  
    6. public class ListFiller : MonoBehaviour {
    7.  
    8.     void ComponentInstantiated(Component component)
    9.     {
    10.         FillList((List)component);
    11.     }
    12.  
    13.     public static void FillList(List list)
    14.     {
    15.         System.Collections.Generic.List<object> items = new System.Collections.Generic.List<object>
    16.         {
    17.             new ListItem(1, "One"),
    18.             new ListItem(2, "Two"),
    19.             new ListItem(3, "Three")
    20.         };
    21.         list.DataProvider = items;
    22.     }
    23. }
    PS I guess you know that you could fill the list from designer when dealing with static values: ;)

    $data_provider.png
     
  34. Hays

    Hays

    Joined:
    Mar 5, 2013
    Posts:
    19
    sir, when a component created, it will register its Id, how can I erase that?
    I need reload the GUI with this function.
     
  35. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Hi,

    I'm not at my dev machine right now. Try this. ComponentManager is a singleton used for accessing components by ID. Its Clear() method should release all the IDs.

    Keep me posted if this works for you. Also, explain a bit more what are you trying to accomplish.
     
  36. Hays

    Hays

    Joined:
    Mar 5, 2013
    Posts:
    19
    that works, thank you, sir.

    what I want to do is a GUI editor for my project. no offence, your designer tools suit common work perfectly. but, my project need load the GUI at runtime, that means I can not pack them within the scene directly.
    as what I said before, I try to pack every single window within a stage, and stored them in the assetbundle file. that just works like a disaster. well, as I see the real reason about this is the adpater class which used in design the GUI.
    so, I turn aside, how about I write a editor, just assembles the components and save them into a XML file, then load them from the XML file later.
    after two days work, I got the first version.

    $editor.png
     
  37. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    So, you got your GUI loading from XML? Well that's a neat stuff! :)

    I had something like this in mind before I did it the Unity way (using its serialization of game object hierarchy).

    Even thought of making an online GUI editor; that's one of the reasons that the Designer DLL is separate from the Editor DLL (so one could use style mappers in runtime).

    Do you use XmlSerializer or some other method of XML serialization?

    Cheers!
     
    Last edited: Apr 9, 2013
  38. ScrappyRMH

    ScrappyRMH

    Joined:
    Apr 11, 2011
    Posts:
    48
    I am having problems getting events to trigger from a Text Field. I used the designer to add a field and then tried to connect an event. I want to filter a list as the user is typing so i want it to trigger at every key press but i can't seem to find an event that works. I can get it to trigger on "click" for when i click the mouse but nothing works for the keyboard. I've tried "Change", "CHANGE", "change", "KeyUp", "KEY_UP" and "key_up" but none of these trigger the event.
     
  39. ScrappyRMH

    ScrappyRMH

    Joined:
    Apr 11, 2011
    Posts:
    48
    I'm also having trouble filling a list. As you mentioned earlier, instead of adding one item at a time to the data provider, I am using the method:

    Code (csharp):
    1. list.DataProvider = items;
    It fills the list but the first item is not selectable. All other items can be selected.

    EDITED: I just noticed.... the first time I assign the list, it works just fine. But if I go back and assign the list again (i allow the user to sort and filter) then the list will not allow me to select the first item. No matter how many times the list is rebuilt, the first item cannot be selected.
     
    Last edited: Apr 10, 2013
  40. ScrappyRMH

    ScrappyRMH

    Joined:
    Apr 11, 2011
    Posts:
    48
    Ok. I've done a little more testing and have found a few things. First, I am still using the method of assigning a list to the dataprovider as in my previous post. When the list is assigned, the list populates on screen. At this point, you cannot select the first item. All other items can be selected, just not the first one. Now, if you scroll one of the scroll bars by even a tiny amount, you can now select the first item. If the list is shorter than the window and not as wide (i.e. no scroll bars) then you will not be able to do anything to select the first item.

    A few other issues....

    1. I have some items that are wider than my list. The horizontal scroll bars appear as expected. If the number of items fit within the vertical size of the window (and doesn't show the vertical scroll bar), I can scroll horizontally. But if the list is longer than the window (and shows the vertical scroll bar) I can't scroll the horizontal scroll bar. It just jitters when i try.

    2. When there are a lot of items in a list and both scroll bars are visible, when you scroll to the last item it is mostly hidden behind the horizontal scroll bar. There needs to be some space to allow that last item to be seen.

    3. When clicking and dragging in the scroll bar, the mouse should be captured so that even if you are not over the scroll bar (but still dragging) it will continue to scroll. This is the expected behavior in most operating systems.
     
  41. ScrappyRMH

    ScrappyRMH

    Joined:
    Apr 11, 2011
    Posts:
    48
    In a previous post addressing knowing when the mouse is over the GUI you said that for version 1.11 I should use this:
    Code (csharp):
    1.     // script attached to a 3D game object
    2.     using eDriven.Gui;
    3.     using UnityEngine;
    4.      
    5.     public class Demo : MonoBehaviour {
    6.         void OnMouseDown () {
    7.             if (MouseEventDispatcher.Instance.MouseTarget == null) {
    8.                 // GUI not under the mouse. Do stuff with a game object.
    9.             }
    10.         }
    11.         void Update () {
    12.             if (Input.GetKeyDown ("space")  FocusManager.Instance.FocusedComponent == null) {
    13.                 print ("space key was pressed");
    14.                 // GUI not focused. Do stuff with a game object.
    15.             }
    16.         }
    17.     }
    I tried that. I have the "using eDriven.Gui" line and then try to test "(MouseEventDispatcher.Instance.MouseTarget == null)". I receive this error: "error CS0103: The name `MouseEventDispatcher' does not exist in the current context".

    So I looked in the API guide and found that MouseEventDispatcher was in the eDriven.Gui.Managers namespace so I used that. But then it doesn't like the Instance. In the end, I can't seem to get this to work. It either won't compile or it won't give the expected result. At best, it gives me the error: "error CS0176: Static member `eDriven.Gui.Managers.MouseEventDispatcher.MouseTarget' cannot be accessed with an instance reference, qualify it with a type name instead"

    Overall, I'm happy that I found this addon. It has allowed the to accomplish a lot more than some of the other Unity GUI solutions that are out there. I just need help with some of the quirks. Thanks!
     
    Last edited: Apr 10, 2013
  42. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    TextField dispatches the following events:
    • textChanging (TextFieldEvent.TEXT_CHANGING) - fired when text changing
    • textChange (TextFieldEvent.TEXT_TEXT_CHANGE) - fired when text changed
    • return (TextField.RETURN) - fired when the Return (or Enter) key was pressed
    If listening for "textChanging" and canceling the event, the text in the textfield won't be changed and the "textChange" event won't fire. So this way you should invalidate input etc.

    I've found bug in this - canceling the CHANGING event prevents the text change but dispatches the CHANGE event. I've fixed it right now (for v1.12).
     
  43. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Will look at it ASAP.
     
  44. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Horiz scroll bar isn't supposed to happen. Will look at it and rewrite the list to remove it.

    Will need no space when I remove the horiz scroll.

    This is the UnityGUI bug. Until they fix it it won't work as on any other OS. :)

    btw this is not the only scrollbar bug (see this and this) which forces me to eventually write my own scrollbar. :cool:
     
  45. dkozar

    dkozar

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

    ScrappyRMH

    Joined:
    Apr 11, 2011
    Posts:
    48
    Why wouldn't a horizontal scroll bar happen? If the text is wider than the list window, i would want it there like it is now. (minus the jitters and blocking the last item)
     
  47. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    With a list, particularly with the list within the combo box - I really don't like it.

    The jitter is because of the UnityGUI scroller.
     
  48. ScrappyRMH

    ScrappyRMH

    Joined:
    Apr 11, 2011
    Posts:
    48
    Code (csharp):
    1.  
    2.     eDriven.Gui.Managers.MouseEventDispatcher.Instance.MouseTarget // until v1.10 (Singleton)
    3.      
    4.     eDriven.Gui.Gui.MouseTarget // from v1.11 (static)
    I'm on v1.11.0 (according to the debug.log) but this still doesn't work. I have
    Code (csharp):
    1. using eDriven.Gui;
    at the top of the page. In the code i have:
    Code (csharp):
    1. if (eDriven.Gui.Gui.MouseTarget == null)
    but it gives me the following:
    error CS0117: `eDriven.Gui.Gui' does not contain a definition for `MouseTarget'

    If i try to type "eDriven.Gui.Gui." and wait for Autocomplete, it doesn't show a "MouseTarget"
     
  49. ScrappyRMH

    ScrappyRMH

    Joined:
    Apr 11, 2011
    Posts:
    48
    In the case of the combo box, i would agree that the horizontal scroll bar shouldn't be there. But in the case of a List, i find it useful. Maybe there should be a flag for "Allow Horizontal Scrolling"
     
  50. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    I've looked at my comment from few days ago - this is still not implemented with v1.11. It goes into v1.12.

    So use the MouseDispatcher thing.