danrer
Topic Author
Posts: 10
Joined: 27 Apr 2019, 18:20

Unity NoesisView

27 Dec 2019, 00:43

Good day. My interface consists of several Windows, such as trade, backpack, and character window. Each of them is made in different xaml files. I need to create a GameObject with NoesisView for each of them, or just one in which I will put a container, and I will create all these Windows in it through Children.Add?

Tags:
 
User avatar
sfernandez
Site Admin
Posts: 1918
Joined: 22 Dec 2011, 19:20

Re: Unity NoesisView

27 Dec 2019, 12:59

Hi, It is better to have a single NoesisView component with a root xaml where you can add the different windows. Usually a Grid root could work, then use Children.Add(), Children.Remove() to add/rem controls.
This way all the input events are handled by the same View, and it will be easier for you.
 
danrer
Topic Author
Posts: 10
Joined: 27 Apr 2019, 18:20

Re: Unity NoesisView

27 Dec 2019, 14:47

Thanks. But how then to implement the movement of these Windows (trade, backpack, and character)? Usually in wpf, I can just call DragMove when I get MouseLeftButtonDown.
I assume that I will have to track the click on each window, and move it relative to the GRID element that it belongs to?
 
danrer
Topic Author
Posts: 10
Joined: 27 Apr 2019, 18:20

Re: Unity NoesisView

28 Dec 2019, 02:21

At the moment, I did it like this. But perhaps there is a better way?
        bool _move;
        Point _offset;

        private void ScienceWindowName_MouseLeftButtonDown(object sender, RoutedEventArgs args)
        {
            Noesis.Grid parentGrid = this.Parent as Noesis.Grid;
            Point mousePosition = Mouse.GetPosition(this);
            _offset = mousePosition;
            _move = true;
        }

        private void ScienceWindowName_MouseLeftButtonUp(object sender, RoutedEventArgs args)
        {
            _move = false;
        }

        private void ScienceWindowName_MouseMove(object sender, RoutedEventArgs args)
        {
            if (_move)
            {
                Noesis.Grid parentGrid = this.Parent as Noesis.Grid;
                Point mousePosition = Mouse.GetPosition(parentGrid);
                this.RenderTransform = new TranslateTransform(mousePosition.X - _offset.X, mousePosition.Y - _offset.Y);
            }
        }

        private void ScienceWindowName_MouseLeave(object sender, RoutedEventArgs args)
        {
            if (_move)
            {
                _move = false;
            }
        }
And if I use this code to register events, can I have any problems?
        protected override bool ConnectEvent(object source, string eventName, string handlerName)
        {
            Type sourceType = source.GetType();
            EventInfo eventInfo = sourceType.GetEvent(eventName);
            if (eventInfo == null)
            {
                Debug.Log($"Not find source event {eventName}");
                return false;
            }

            Type thisType = this.GetType();
            MethodInfo eventHandler = thisType.GetMethod(handlerName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            if (eventHandler == null)
            {
                Debug.Log($"Not find method {handlerName}");
                return false;
            }

            Delegate delegateHandler = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, eventHandler);
            if (delegateHandler == null)
            {
                Debug.Log("Fail created delegete");
                return false;
            }
            eventInfo.AddEventHandler(source, delegateHandler);
            return true;
        }
 
User avatar
sfernandez
Site Admin
Posts: 1918
Joined: 22 Dec 2011, 19:20

Re: Unity NoesisView

07 Jan 2020, 11:26

Window class is not part of Unity integration because the system window implementation is already provided by Unity and we don't have control over that part.

In Unity you should implement your own Window/Dialog control and add those window-drag (or even docking) capabilities to your implementation. That is usually done by registering to MouseLeftButtonDown to detect when user clicks over the title border area, capture the mouse and listen to MouseMove events to update window position until MouseLeftButtonUp is fired to release the capture.

To manage the position you can place all the windows inside a Canvas panel and use Canvas.Left and Canvas.Top properties (or use RenderTransform as you did). You can also change ZIndex property to determine the z-order of the windows.

Regarding the ConnectEvent function, as explained in our Events tutorial, you don't need to use reflection to attach to the events, just use the input parameters to explicitly add the corresponding handler:
protected override bool ConnectEvent(object source, string eventName, string handlerName)
{
  if (eventName == "MouseLeftButtonDown" && handlerName == "ScienceWindowName_MouseLeftButtonDown")
  {
    ((UIElement)source).MouseLeftButtonDown += this.ScienceWindowName_MouseLeftButtonDown;
    return true;
  }
  if (eventName == "MouseLeftButtonUp" && handlerName == "ScienceWindowName_MouseLeftButtonUp")
  {
    ((UIElement)source).MouseLeftButtonUp += this.ScienceWindowName_MouseLeftButtonUp;
    return true;
  }
  if (eventName == "MouseMove" && handlerName == "ScienceWindowName_MouseMove")
  {
    ((UIElement)source).MouseMove += this.ScienceWindowName_MouseMove;
    return true;
  }
  return false;
}
That code is something we want to automatically generate in the future with our plugin, but there is already someone that implemented a Unity script to do it: viewtopic.php?f=3&t=1670&hilit=ConnectEvent

Who is online

Users browsing this forum: No registered users and 1 guest