Search Unity

eDriven Q&A

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

  1. huodong

    huodong

    Joined:
    Aug 7, 2012
    Posts:
    4
    I need <MyCustomComponent (extand by ViewStack)> under can add node (e.g button) like ContainerAdapter. How do. :)
     
    Last edited: Mar 12, 2013
  2. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Something like the TabNavigator component? Buttons on top switching the displayed ViewStack item?

    Could you post a drawing of what you are trying to accomplish?

    Thanks ^^
     
  3. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    This is most probably due to layout of the container the dialog is added to.

    Some sorts of layout (like vertical box layout) normally react on each child size change (so they could resize the container and adapt other children to this new size).

    When having draggable and resizable items, your container should have the AbsoluteLayout set. This layout doesn't resize the container on child size change, nor it resizes its children (chidren are independant, they could overlap etc.)

    You could use the ADDED event defined in the FrameworkEvent class.

    For instence, when component is being added, it (the added component) fires the FrameworkEvent.ADDED event.
    At the same time, the container (the component is being added to) dispatches the FrameworkEvent.CHILD_ADDED event. So, it's pretty FLEXible ;)

    This of course works for all the components (not only dialogs). Note: eDriven dialogs are treated as any other panels/containers and doesn't use GUI.Window.

    For subscribing to events (when += notation not available) you should use the folowing notation:

    Code (csharp):
    1. AddEventlistener(FrameworkEvent.ADDED, YourEventHandler)
    Also for freeing up resources, instead of -=, you should use:

    Code (csharp):
    1. AddEventlistener(FrameworkEvent.ADDED, YourEventHandler)
    That was great! I appreciate it!! :)

    No, you should use the GuiLookup class, as described in the manual:

    Code (csharp):
    1. Button button = GuiLookup.GetComponent("button1") as Button;
    This returns the component (not the adapter, adapters are used for setting things up in designer). So, using the string ID should be the easiest way to reference a component. But you should be careful, and do it only after you are sure the component is being added to stage (in the custom script you should override a specific message - also explained in the manual).

    Event handlers attached to stage should fire when each bubbling event from the children is received. The important point is that your custom events should bubble.

    You could, although the prefab instances would change by the framework upon the multiple instantiation of the same prefab (that's a technical issue, related to using adapter GUIDs which have to be unique for each component).

    However, all the style and audio mappers (as well as the other non-designer related stuff) could easily be turned to prefab and reused.
     
    Last edited: Mar 12, 2013
  4. tomshreds

    tomshreds

    Joined:
    Feb 25, 2013
    Posts:
    32
    Very informative response, thanks a lot! That helped :D

    Now only one concern left:

    My game has a toolbar, so when you click on let's say "Employee Management" it would open a dialog.

    But how can I bind an event on a Dialog if it doesn't exist yet? Check the following example:

    You can see more formatted version here: http://hastebin.com/wiyoqoqoso.cs

    So basically, I'd need to open a dialog ONLY once I clicked on my toolbar button. Should I have all dialog on the screen at the same time but just toggle the "Visible" property to FALSE to keep them hidden?

    Also I can't bind the event in the Start() else it would crash when the Dialog is not there. How would you do this?

    I really love the event system, I made a Node.js/Javascript framework based on that callback principle. So useful and straightforward.

    Thanks again for your great support!
     
  5. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    You should not do it on Start, but on ComponentInstantiated handler (in a MonoBehaviour script attached to the component, Manual - page 46):

    Code (csharp):
    1. void ComponentInstantiated(Component component) { // eDriven.Gui.Components.Component
    2.     Debug.Log("Initializing component:" + component);
    3. }
    4.  
    Additionally, you could add the event listener to the dialog from the designer. This is done via the Events display in the eDriven.Gui Designer window.

    Dialogs in the designer are usually components having the factory mode turned on. Each instantiated dialog maps to handlers set to its factory (adapter). :)

    So, you should 1) setup your dialog, 2) turn the factory mode on (this should make it invisible, e.g. would not be instantiated with other components), 3) add your custom script to it (having event handlers), 4) map event handlers graphically, using the designer.
     
  6. tomshreds

    tomshreds

    Joined:
    Feb 25, 2013
    Posts:
    32
    Thanks again for the quick and detailed answer! Everything you said works perfectly, this is awesome!

    I'm wondering though, once this is done. How do you show the dialog on the screen? I can't do a GuiLookup.GetComponent() on it so I tried with Instantiate, I searched in the Dialog API but I guess there's a totally different API to instantiate stuff. Or do I need to make a prefab with the dialog and instantiate it?

    There's something on Page 59 on the docs, but I'm not sure I'm looking at the right thing.

    Sorry for the number of questions :S and Thanks!
     
    Last edited: Mar 12, 2013
  7. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Please take a look at eDriven/Demo/Gui/Designer/DialogDemo for the usage of PopupManager.

    Code (csharp):
    1. PopupManager.Instance.AddPopup(_yourDialog);
    What this does is - it pops up the dialog in the special stage that is rendered in front of all other (custom) stages.
     
  8. tomshreds

    tomshreds

    Joined:
    Feb 25, 2013
    Posts:
    32
    Thanks for your answer, looking at that example helped me quite a bit :D

    Using this method, do I have to programatically rebind everything each time I instantiate a Dialog? Because right now, I open it, events don't work, then I remove old events and re-add them back now they work, then I close the dialog, re-open it and events do not work anymore.

    Is it supposed to work like that?

    Also is this the proper way of filling a list?
    List list = GuiLookup.GetComponent("Employe eList") as List;
    Debug.Log(list.DataProvider);
    list.DataProvider = new System.Collections.Generic.List<object>(){ new ListItem(1, "Employee Name") };

    Thanks
     
    Last edited: Mar 13, 2013
  9. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    No, you have to do nothing.

    The purpose of the adapter is as follows:

    eDriven.Gui adapters are MonoBehaviours instantiating the "real" GUI controls when the application being run. But, when in "factory" mode, they do not instantiate anything on start - instead, they "spit up" controls on demand - when you call them. Not only this, but they map all the properties set in the adapter (size, color, event handlers...) to each created control instence. :)

    No. Just try to attach event handler script directly to sub-controls (e.g. dialog buttons). Look at the DialogDemo and check out the scripts attached to each dialog child. Of course, you could attach a single script to the dialog itself, and rely on event bubbling, but then you need to use IDs on your buttons (to find out which button is being clicked).

    I believe it is.

    However, for filling the list from designer, drag the appropriate DataProvider from the eDriven menu to a game object containing the ListAdapter! In demos, this is not clearly visible, but you should select the list game object and examine the inspector. Below all the (blue-colored) editor panels, you should find the data provider script, supplying the default values to the list control.
     
    Last edited: Mar 13, 2013
  10. Hays

    Hays

    Joined:
    Mar 5, 2013
    Posts:
    19
    how can I remove the dialog's black border when I use mappers with my custom skin?

    $ui_bug.jpg
     
    Last edited: Mar 13, 2013
  11. dkozar

    dkozar

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

    the overlay mapping is defined in ComponentStyleMapper. This setting is then being inherited by all the other eDriven style mappers.

    You should either turn the overlay completely off (ShowOverlay setting), or supply your custom overlays using the OverlayStyle and DisabledOverlayStyle settings (mapping to your skin/styles).

    The purpose of overlay is to provide rendering of your custom stuff *over* the control - things like border, glares, flares etc.

    Your custom overlay should most probably be a transparent image, having non-transparent border, and properly set up as a GUIStyle (it's border setting is the important one).

    More on component rendering cycle in this post.

    Cheers! :)
     

    Attached Files:

    Last edited: Mar 13, 2013
  12. Hays

    Hays

    Joined:
    Mar 5, 2013
    Posts:
    19
    finally I got it. as you say, I made another transparent image, and use it with overlay skin.
    as default there is a black border with dialog right?
     
  13. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Yes, the 1px black border is the default hardcoded thing.

    eDriven.Gui generates GUIStyles from the code lazily (singletons) when no style is being applied via the mapper.
     
  14. tomshreds

    tomshreds

    Joined:
    Feb 25, 2013
    Posts:
    32
    Hi,

    1) For some reason, event bindings do not get saved at all. I've got my script as component on each buttons.

    Using auto save or not, I can see them even in the scene view. But when I restart the game the bindings do nothing, until I remove them and put them back.

    Is there anything I must do to make sure everything gets saved (am I doing something wrong)? My dialog is in factory mode, every button has IDs, etc.

    So far I use:
    Button spawnButton = GuiLookup.GetComponent("SpawnButton") as Button;
    spawnButton.AddEventListener(MouseEvent.CLICK, SpawnEmployeeButton);
    Button closeButton = GuiLookup.GetComponent("CloseButton") as Button;
    closeButton.AddEventListener(MouseEvent.CLICK, CloseButtonClicked);
    And it works fine, but automatic bindings would be great :D

    I can make a video to show you if you want.

    ---

    2) Now I'm having one problem. I think I really should use Event Bubbling.

    Because my "ComponentInstantiated" method is getting called as many time as I have that script references on my GUI components.

    So 1 for the Dialog, 2 for the two buttons = 3 calls. Which cause a problem in my case. Anything to prevent this?

    I will try to get bubbling working right now. I read the part in the docs, and checked the code from the EventBubbling code demo and I'm still unsure about how to subscribe my buttons to events..

    ---

    3) So far I have this (For some reason btn.Id is always null even if I specified IDs for the component using the panels):
    public void ButtonClickHandler(Event e) {
    Button btn = e.Target as Button;
    if (null == btn)
    return;

    if (btn.Id == "SpawnButton") {
    SpawnEmployeeButton(e);

    } else if (btn.Id == "CloseButton") {
    CloseButton(e);
    }
    }

    It's an event binding right on the Dialog.

    ---

    BONUS QUESTION! Any way of adding buttons in the title bar? I'd like to get an X up there :D

    And by the way, your asset really is a charm. I love to use it, I can now make a very strong and versatile GUI for my game :D

    Thanks!
     
    Last edited: Mar 13, 2013
  15. Hays

    Hays

    Joined:
    Mar 5, 2013
    Posts:
    19
    sir, I got another question.
    when the level was changed, seems like mappers in prev scene have effect on the entire scene.
    what can I do?
     
  16. dkozar

    dkozar

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

    yes, this happens because the framework is over-optimized :)

    The framework each style mapper the first time it is being requested by any component, and doesn't destroy them on scene change. This has a nice effect of PopupManagerStage children (e.g. dialogs) stay alive even when scene changing. :)

    I'm planning to make a switch on style mapper which would then propagate to the next level only when checked, or else it would reinitialize on scene change.

    Until then, please use named mappers instead of the "default" ones - for styles you wish to have different in multiple levels (scenes).

    For example, if you want to have a different button look on scenes 1 and 2, don't use the "Default" mapper option (at least in the second scene):
    • You should give your first scene mapper the ID of (say) "button1"
    • You should give your second scene mapper the ID of "button2"
    Now, each of the buttons in the first scene should have:

    Code (csharp):
    1. button.StyleMapper = "button1";
    And in the second scene:

    Code (csharp):
    1. button.StyleMapper = "button2";
     
  17. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Nice to see you are using GuiLookup and C# event subscription (advanced user) ;)

    Here's the basic workflow for adding the event listener to a GUI component:

    1. Create your event handler script (note that the same script could be reused and attached to multiple components):



    Note that - for the script/methods to be found by designer - you got to obey the method signature, which means:
    • methods must be public
    • methods must receive a single parameter of eDriven.Core.Events.Event type
    So, if your script has at least a single method of the described signature, it will be displayed in the Events display.

    2. Attach your script to a component. Important: this has to be done when not in play mode:



    3. Pick your event from the list on the left (or write the name of the event into the text field), and pick the method name from the list on the right:



    4. Press the Add handler button. The mapping appears below:



    5. When your component dispatches the event we are listening to (clicking the button in this example), the event handler will fire:



    Example event handler script is in the attach.
     

    Attached Files:

    Last edited: Mar 14, 2013
  18. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    1. Remove the ExampleEventHandlerScript from the button (and remove all the event mappings using this script).
    2. Attach the same script to the stage containing the button as the descendant.

    Your event mappings for stage should now look like this:



    Since the click event bubbles (and we are listening for the "click" event) our event handler fires even it is not subscribed directly to the button clicked, but to one of its ancestors. That is event bubbling.

    More about event constants:

    You could subscribe to an event by:

    1. Using the string:
    Code (csharp):
    1. button.AddEventListener("click", MyClickHandler);
    2. Using the constant containing that same string:

    Code (csharp):
    1. button.AddEventListener(eDriven.Core.Events.MouseEvent.CLICK, MyClickHandler); // MouseEvent.CLICK contains string "click"
    3. Using the designer, by writing "click" into text field, or picking it from the drop down (if available).





    4. Using the "+=" notation, if available:

    Code (csharp):
    1. button.Click += MyClickHandler;
     
  19. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    This is a normal behaviour. When attaching the same script to multiple components, the ComponentInstantiated method is being run multiple times. Think of it as a "Start" method of MonoBehaviour.

    Use ComponentInstantiated only on components you want to reference (use different scripts for each component).
     
  20. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    What you found is a bug! :)

    I'm not propagating the dialog IDs to components at all. Now I've fixed it. Will work correctly with eDriven.Gui 1.9!

    So, you will be able to check the instantiated component using the adapter ID, using the following code:

    Code (csharp):
    1. using eDriven.Gui.Components;
    2. using UnityEngine;
    3. using Event=eDriven.Core.Events.Event;
    4.  
    5. public class ExampleEventHandlerScript : MonoBehaviour {
    6.  
    7.     public void ClickHandler(Event e)
    8.     {
    9.         Debug.Log("Clicked: " + e.Target);
    10.         Button button = e.Target as Button;
    11.         if (null != button)
    12.             Debug.Log("Button ID: " + button.Id);
    13.     }
    14. }
     
  21. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    1. If using C# approach, when adding children - just add it to Tools - instead of the content:

    Code (csharp):
    1. panel.Tools.AddChild(_myButton);
    2. Using the designer:

    All the buttons must be children of the dialog itself. But, if dragging them from the hierarchy to a Tools or Button group, they will appear there:







    Note: this feature is not completely stable yet, so you might be doing this when not in play mode.
     
  22. Hays

    Hays

    Joined:
    Mar 5, 2013
    Posts:
    19
    sir, exactly do what U say, but it not works.
    mappers with one skin works fine, mappers with two skins works badly, when the scene was changed

    by the way, no mappers at all, as default there gonna draw some color rectangle instead?

    P.S: my workmate says your smile looking good
     
    Last edited: Mar 14, 2013
  23. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    I see. I should work on mapper reset on screen change ASAP.
     
  24. tomshreds

    tomshreds

    Joined:
    Feb 25, 2013
    Posts:
    32
    OMG, Great answers! I wasn't expecting that much info, this is awesome!

    Any ETA as of when 1.9 will be released for the .Id bug?

    Thanks again for so much good answers!

    1) Is it possible to throw a Button on the stage and use the constrains or position to position it somewhere on the screen instead of inside another component? Because right now I'm trying to make a bottom toolbar for my game and I can't get a button at the bottom of my window. Thanks!

    FYI Events do not unbind themselves in this case:
    If I add a script with events on a component. Then bind an event to it and remove the script from that component. Next time I'll run the game I'll get messages like these:

    Script EmployeeManagementDialogController not found on SpawnButton (UnityEngine.GameObject)
    UnityEngine.Debug:LogWarning(Object)
    eDriven.Gui.Designer.EventMappingDescriptor:processListener(ComponentAdapter, Component, EventMapping, Boolean)
    eDriven.Gui.Designer.EventMappingDescriptor:processListeners(ComponentAdapter, Component, Boolean)
    ComponentAdapter:cd9e3af53bf5dae956c352de25bc3cee3(Component)
    ComponentAdapter:produce(Boolean, Boolean)
    ContainerAdapter:HandleChildren(Boolean, Boolean, Container)
    PanelAdapter:HandleChildren(Boolean, Boolean, Container)
    DialogAdapter:HandleChildren(Boolean, Boolean, Container)
    ComponentAdapter:produce(Boolean, Boolean)
    eDriven.Gui.Designer.GuiLookup:produce(String)
    EmployeeManagementDialogController:Update() (at Assets/Scripts/GUI/EmployeeManagementDialogController.cs:33)
     
    Last edited: Mar 14, 2013
  25. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Soon. Got to fix some iOS issues for v1.9. :)

    For using component constrains your container must be in AbsoluteLayout mode (I should make it obvious in the designer though).

    I didn't want to remove handle mappings automatically, but decided to throw a warning for user to decide what to do with the mapping.
     
  26. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Yes it is (HttpConnector is basically a wrapper around the WWW class)

    What I do in my WebPlayer applications is:
    1. I'm relying on the browser handling cookies when in browser
    2. I'm handling the cookie manually when NOT in browser (i.e. in UnityEditor, Windows app, iOS)
    I'm retrieving the cookie from my PHP/Drupal backend in the form of SessionId - SessionName pair (2 strings) as the response of the successful login (and username too). Then I save it to a variable:

    Code (csharp):
    1. _cookie = string.Format("{0}={1}", SessionName, SessionId);
    I have a small logic for building headers which will be sent with each consequent request:
    Code (csharp):
    1. readonly Hashtable _headers = new Hashtable { { "GetContent-type", "application/json" } };
    2. public Hashtable Headers
    3. {
    4.     get
    5.     {
    6.         if (!Application.isWebPlayer  null != _cookie)
    7.             _headers["Cookie"] = _cookie; // we are not in browser - add cookie!
    8.         else
    9.             _headers.Remove("Cookie");
    10.         return _headers;
    11.     }
    12. }
    I'm using the single HttpConnector instance to send data to server:
    Code (csharp):
    1. private readonly HttpConnector _nodeConnector = new HttpConnector();
    And here is how I build up my request and send the data:
    Code (csharp):
    1. string data = JsonWriter.Serialize(comment); // my data is the object serialized to JSON string
    2. UTF8Encoding encoding = new UTF8Encoding();
    3.  
    4. WebRequest request = new WebRequest(
    5.     _endpoint + "comment.json",
    6.     encoding.GetBytes(data),
    7.     Headers
    8. );
    9.  
    10. _nodeConnector.Send(
    11.     request,
    12.     new Responder(
    13.         delegate
    14.             {
    15.                 Debug.Log("Success.");
    16.             },
    17.         delegate(object fault)
    18.             {
    19.                 Debug.Log("Error: " + fault);
    20.             }
    21.         )
    22.     );
    23. }
    Enjoy! :)
     
    Last edited: Mar 14, 2013
  27. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    There is an exception specific for iOS build (related to AOT compilation) stating "Ran out of trampolines of type 2".

    Code (csharp):
    1. (Filename: /Applications/buildAgent/work/812c4f5049264fad/Runtime/ExportGenerated/iPhonePlayer-armv7/UnityEngineDebug.cpp Line: 43)
    2.  
    3. Ran out of trampolines of type 2 in '/private/var/mobile/Applications/A52691D3-72AF-45CC-8DF6-5CFB8BBDCA61/testapp.app/Data/Managed/mscorlib.dll' (128)
    How to fix it: you have to go to player options for iOS platform, and manually insert nimt-trampolines=512 (see image below, Unity 3.5.7f5)

    More on this issue here.

     

    Attached Files:

    Last edited: Mar 15, 2013
  28. Hays

    Hays

    Joined:
    Mar 5, 2013
    Posts:
    19
    hey, be be honest, your system is amazing. but, as far as I can see, use this system must have many test. can U just offer the source code to anyone who paid this system ?
     
  29. dkozar

    dkozar

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

    I'm actually offering the high-level sources with the package. As you can see, the system is totally extensible and people can build their own components.

    As for the GUI "kernel" source - I'm the only maintainer, I keep solving the reported bugs. For instance, I'm currently working on the StyleMapper problem you reported, and this will be solved with v1.10 (unfortunately not ready for 1.9 which will ship this weekend). I'm also documenting the framework usage and answer the questions.

    I've been developing this for years (*literally*), so you might understand my interest for keeping the source (currently) for myself.

    Danko
     
  30. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    I'm also planning to include the additional drag drop demo (the inventory example) with v1.10:

     
  31. Hays

    Hays

    Joined:
    Mar 5, 2013
    Posts:
    19
    well,sir. our group got many problems with this system. I understand the way you want to keep the source code, years of hard work, I know that and really appreciate that.

    StyleMapper problem I just solved it, but others came out. such as factory mode with assetbundle work just like a disaster, initialize order, auto-save will clear all your work when U working on scene changing....

    well, those problems are really really serious. that's why I ask for the source code.
     
  32. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Unfortunately, you have to rely on myself as an author.

    And believe me: I'm the best pick to handle the current bugs. And will eventually handle them all.

    Thanks for the understanding.
     
  33. Hays

    Hays

    Joined:
    Mar 5, 2013
    Posts:
    19
    I got it. see your work.
    I got some questions.
    1.whether tooltip can be muti-line?
    2.how to create stage with factory mode when the level was changed?
    3.how was the stage registered when use factory mode with assetbundle?
    4.the initialize order when work with multiple stages
    5.why the stage's RenderingRect is invalid with the value {0, 0, 0, 0}
    6.why everything appear after I resize screen size.(before this action, every controls are hidden)
     
  34. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Yes. Drop the single instance of TooltipStyleMapper in the scene and set your GUIStyle (having wordWrap set) as its LabelStyle.

    Stages are never created from factories: they are tranparent, blank canvases onto which you add things.

    You should create the stage statically, using the Gui class or using the designer (creating StageAdapter).

    Didn't quite get it (?) When using the asset bundle you basically load another Unity app into place. The old one gets destroyed.

    Random. They are registered to the manager at the order the Start() method is being called on each script (i.e. unpredictable).
    However, the moment they are registered, they get sorted by Z-Order and start working together in sorted manner (back to front).
    If you subscribe to FrameworkEvent.CREATION_COMPLETE on the stage, you will get notified when all the children creation and layout process is finished. This should fire in sorted order on each stage.

    You should wait until the FrameworkEvent.CREATION_COMPLETE is being fired (after layout is done).

    Don't know about this problem. Could you get me some screenshots?
     
  35. Hays

    Hays

    Joined:
    Mar 5, 2013
    Posts:
    19
    sir, the sixth problem should the same like fifth.
    when FrameworkEvent.CREATION_COMPLETE happened, and how can I subscribe to it
     
  36. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Event subscription is the basis of publish-subscribe event systems.

    There are two parts to it: referencing and subscription

    1. Referencing:

    There are multiple ways of getting the reference to your Stage.

    If referencing from within the Gui class, you should use this.Stage (but only after the initialization is passed).

    If within a simple MonoBehaviour script attached to a Stage game object using the designer (more in the manual):

    Code (csharp):
    1. void ComponentInstantiated(Component component) {
    2.     // component is Stage (if script attached to the stage game object)
    3. }
    2. Subscription:

    After you get a reference to stage, you should either:

    Code (csharp):
    1. stage.AddEventListener(FrameworkEvent.CREATION_COMPLETE, YourHandler); // using the constant
    or:

    Code (csharp):
    1. stage.AddEventListener("creationComplete", YourHandler); // using string
    or (just because each eDriven.Gui component provides it):
    Code (csharp):
    1. stage.CreationCompleteHandler += YourHandler; // using the += notation (slower than above, don't use it on ton of objects)
    or using the designer, using the Events tab and subscribing for "creationComplete".

    Please look at this post ("More about event constants").
     
  37. Hays

    Hays

    Joined:
    Mar 5, 2013
    Posts:
    19
    within a simple MonoBehaviour script attached to a Stage game object, subscribe creation complete events in which function should be OK, Start(), Awake(), or any functions else?
     
  38. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    None of the above, but the one I mentioned:

    Code (csharp):
    1. void ComponentInstantiated(Component component) {
    2.     // component is Stage (if script attached to the stage game object)
    3. }
    If you are familiar with Unity's messaging system, you'll understand.

    ps Please read the manual! :)
     
    Last edited: Mar 22, 2013
  39. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Hi, could you please write the exact steps to reproduce this problem?

    It happened to me once, but couldn't reproduce it.

    Thanks.
     
  40. Hays

    Hays

    Joined:
    Mar 5, 2013
    Posts:
    19
    sir, while U design your UI, running in the game view, then change level with logic code, U will see new GameObject in the Hierarchy window, but as U can see, all of your UI in the prev scene just missing from the Hierarchy window.now U stop running, save the work follow the prompts, whole work just gone.
     
  41. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Will look at it and solve it ASAP (for v1.10).

    (I assume this happens because I didn't reset the persisted changes when changing the scene (so the system basically thinks that all the objects have been deleted).
     
  42. tomshreds

    tomshreds

    Joined:
    Feb 25, 2013
    Posts:
    32
    I'm trying to make a toolbar for my game. I have simple square buttons and I'm currently using them as a button's icon.

    It works fine, supports tooltips which is GREAT but the image gets upscaled a little and I'd need to get rid of the button (gray zone) and keep only my toolbar button image.

    See here for an example: http://cl.ly/image/0F2B3Y2M0D45

    Any suggestions as of how to do so?

    Thanks!
     
  43. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    You have multiple options, here are the first two:

    1. Using a style mapper, style your button with a GUIStyle having the padding (0, 0, 0, 0) and ImagePosition = ImageOnly.
    2. Don't use buttons - instead use images (Image control):

    Code (csharp):
    1. Image img = new Image
    2. {
    3.     Texture = yourTexture,
    4.     Tooltip = yourTooltip
    5. };
    Images are used in LoadImages demo. They internally measure the supplied texture for sizing (if you don't set the explicit width height).
     
  44. tomshreds

    tomshreds

    Joined:
    Feb 25, 2013
    Posts:
    32
    Hi!

    I'm now trying to use StyleMappers. I read the docs and came with this:
    Code (csharp):
    1.  
    2. using eDriven.Gui.Mappers;
    3. using eDriven.Gui.Components;
    4. using eDriven.Gui.Graphics.Base;
    5. using eDriven.Gui.Util;
    6. using UnityEngine;
    7. using Rect = eDriven.Gui.Graphics.Rect;
    8.  
    9. public class ToolBarButtonStyle {
    10.    
    11.     private static GUIStyle _instance;
    12.     public static GUIStyle Instance {
    13.         get {
    14.             if (_instance == null) {
    15.                 _instance = new GUIStyle();
    16.                 Initialize();
    17.             }
    18.             return _instance;
    19.         }
    20.     }
    21.  
    22.     private ToolBarButtonStyle() {
    23.         // constructor is protected
    24.     }
    25.  
    26.     private static ProgramaticStyle _style;
    27.  
    28.     private static void Initialize() {
    29.         _instance.name = "ToolBarButtonStyle";
    30.  
    31.         _style = new ProgramaticStyle
    32.                      {
    33.                          Style = _instance,
    34.                          ImagePosition = ImagePosition.ImageOnly,
    35.                          Padding = new RectOffset(0, 0, 0, 0)
    36.                      };
    37.  
    38.         _style.Validate();
    39.     }
    40. }
    41.  
    But now to use it, I'm a bit lost. Do I have simply to add "ToolBarButtonStyle" in the StyleMapper field of my button? If so it doesn't currently work for me so I guess there's something I do wrong. Any idea? Is my style mapper okay? I based myself on the GreenButton example.

    Thanks!
     
  45. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    If you are trying to use it, you have nothing with the code except this:

    Code (csharp):
    1. component.StyleMapper = "yourStyleMapperId";
    Style mappers are scripts that should be chosen from the Unity Editor menu and added to arbitrary game objects in the scene. Using them you could map any GUIStyle from and GUISkin to your component instance (check out any demo hierarchy to see how they are being used).

    You might choose between the available style mappers. Their number will eventually grow.

    For styling a Button, you should use the ButtonStyleMapper. And so on.

    (The singleton code above generates the default, "hardcoded" GUIStyle (that is being displayed if no style mapper applied). But that's another story.)
     
  46. tomshreds

    tomshreds

    Joined:
    Feb 25, 2013
    Posts:
    32
    Ok so, I should 1) Add my new ToolBarButtonStyleMapper (which nows inherits ButtonStyleMapper) to my Button so use it as the StyleMapper. Then I'd just have to set its StyleMapper value to ToolBarButtonStyleMapper?

    I currently always use the live editor to design my controls, so I have almost no eDriven.Gui code except for events so far.

    And 2) you're saying that my code wasn't all useful? What about just this:

    Code (csharp):
    1.  
    2. using eDriven.Gui.Mappers;
    3. using eDriven.Gui.Components;
    4. using eDriven.Gui.Graphics.Base;
    5. using eDriven.Gui.Util;
    6. using eDriven.Gui.Mappers.Styles.Dialog;
    7. using UnityEngine;
    8. using Rect = eDriven.Gui.Graphics.Rect;
    9. using eDriven.Gui.Mappers.Styles.Button;
    10.  
    11. public class ToolBarButtonStyle : ButtonStyleMapper {
    12.    
    13.     private static ProgramaticStyle _style;
    14.  
    15.     private static void Initialize() {
    16.         _style = new ProgramaticStyle
    17.                      {
    18.                          ImagePosition = ImagePosition.ImageOnly,
    19.                          Padding = new RectOffset(0, 0, 0, 0)
    20.                      };
    21.  
    22.         _style.Validate();
    23.     }
    24. }
    25.  
    I have no errors but it doesn't show the no padding button at all.

    There seems to be something wrong but I don't know what's wrong. Any cue about this? Thanks again!
     
  47. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    I'll write a short article on creating custom style mappers tonight, OK? Thanks
     
  48. tomshreds

    tomshreds

    Joined:
    Feb 25, 2013
    Posts:
    32
    Perfect, I'll try to fiddle my way around meanwhile. Thanks for your time I appreciate it and I cannot wait for that article :)
     
  49. dkozar

    dkozar

    Joined:
    Nov 30, 2009
    Posts:
    1,410
    Don't waste your time because I guess I didn't explain it nowhere in a single sentence. This is kinda of complex - includes 2 additional classes and your control class decoration using the custom attributes.
     
  50. tomshreds

    tomshreds

    Joined:
    Feb 25, 2013
    Posts:
    32
    Ok wow XD Thanks for saving me hours of head scratching! I'll be waiting for the article then :)