Inheritance: System.NotifyPropertyChangedBase
        public void Save(MainViewModel viewModel)
        {
            GestSpaceData space = new GestSpaceData();
            foreach(var tileVm in viewModel.Tiles.Where(t => !t.IsUnused))
            {
                var tile = new TileData();
                space.Tiles.Add(tile);
                if(!tileVm.TakeSuggestedName)
                {
                    tile.ForcedName = tileVm.Description;
                }
                tile.X = (int)tileVm.Position.X;
                tile.Y = (int)tileVm.Position.Y;
                if(tileVm.SelectedPresenterTemplate != null)
                    tile.PresenterTemplate = tileVm.SelectedPresenterTemplate.Description;
                if(tileVm.SelectedGestureTemplate != null)
                    tile.GestureTemplate = tileVm.SelectedGestureTemplate.Name;

                tile.Program = tileVm.FastContext;
                foreach(var evtVm in tileVm.Events)
                {
                    var evt = new EventData();
                    tile.Events.Add(evt);
                    evt.Name = evtVm.Name;
                    if(evtVm.Command != null)
                        evt.Command = evtVm.Command.Script;
                }
            }
            if(viewModel.CurrentTile != null)
            {
                space.LastX = (int)viewModel.CurrentTile.Position.X;
                space.LastY = (int)viewModel.CurrentTile.Position.Y;
            }
            Save(space);
        }
        public void Load(MainViewModel viewModel)
        {
            viewModel.CurrentTile = null;
            viewModel.Tiles.Clear();
            viewModel.Tiles.Add(new TileViewModel()
            {
                Presenter = PresenterViewModel.Unused
            });
            var spaceData = GetSpaceData();
            foreach(var tile in spaceData.Tiles)
            {
                var tileVm = new TileViewModel();
                tileVm.Position = new System.Windows.Point(tile.X, tile.Y);
                tileVm.Main = viewModel;
                if(tile.ForcedName != null)
                {
                    tileVm.Description = tile.ForcedName;
                }
                tileVm.SelectedGestureTemplate = viewModel.GestureTemplates
                                                    .FirstOrDefault(g => g.Name.Equals(tile.GestureTemplate, StringComparison.InvariantCultureIgnoreCase));
                tileVm.SelectedPresenterTemplate = viewModel.PresenterTemplates
                                                    .FirstOrDefault(g => g.Description.Equals(tile.PresenterTemplate, StringComparison.InvariantCultureIgnoreCase));

                tileVm.FastContext = tile.Program;
                foreach(var evt in tile.Events)
                {
                    var evtVm =
                        tileVm.Events
                          .FirstOrDefault(e => e.Name.Equals(evt.Name, StringComparison.InvariantCultureIgnoreCase));
                    if(evtVm != null)
                        evtVm.Command.Script = evt.Command;
                }
                viewModel.Tiles.Add(tileVm);
            }
            viewModel.SelectTile(new System.Windows.Point(spaceData.LastX, spaceData.LastY));
        }
 public DebugViewModel(MainViewModel mainViewModel)
 {
     this.main = mainViewModel;
     Subscribe(main.SpaceListener);
 }
        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {

                listener = new ReactiveListener();
                var spaceListener = new ReactiveSpace(listener);

                controller = new Controller(listener);

                ViewModel = new MainViewModel(spaceListener);

                var ui = SynchronizationContext.Current;

                //listener
                //	.FingersMoves
                //	.SelectMany(f => f.ToList().Select(l =>
                //	new
                //	{
                //		Key = f.Key,
                //		Fingers = l
                //	}))
                //	.Subscribe(f =>
                //	{
                //		Console.WriteLine("finger");
                //		try
                //		{
                //			//var max = f.Fingers.Select(ff => GetAngle(ff)).Where(a => a != null).Select(a => a.Value).Max();
                //			var av = f.Fingers.Select(ff => GetAngle(ff)).Where(a => a != null).Select(a => a.Value).Average();
                //			Console.WriteLine("av : " + ((int)av));
                //		}
                //		catch
                //		{
                //			Console.WriteLine("Ex");
                //		}
                //	});

                var centers =
                    listener
                    .FingersMoves()
                    .SelectMany(f => f)
                    .Buffer(TimeSpan.FromMilliseconds(200), TimeSpan.FromMilliseconds(100))
                    .Where(b => b.Count > 0)
                    .Select(b => KeepPopularFinger(b))
                    .Select(v => new
                    {
                        Finger = v.First().Id,
                        Position = new Leap.Vector(v.Average(m => m.StabilizedTipPosition.x), v.Average(m => m.StabilizedTipPosition.y), 0.0f),
                    });

                var moveCenter = listener
                    .FingersMoves()
                    .SelectMany(f => f)
                    .CombineLatest(centers, ViewModel.SpaceListener.IsLocked(), (p, center, locked) => new
                    {
                        Center = center,
                        Position = p.StabilizedTipPosition.To2D(),
                        Move = p.StabilizedTipPosition.To2D() - center.Position,
                        Locked = locked,
                        Finger = p
                    })
                    .Where(p => p.Center.Finger == p.Finger.Id)
                    .Where(p => !p.Locked);

                moveCenter
                    .ObserveOn(ui)
                    .Subscribe(o =>
                    {
                        ViewModel.SelectionPosition = new Point(o.Move.x, o.Move.y);
                    });

                moveCenter
                .Where(o => o.Move.Magnitude >= 50.0)
                .Sample(TimeSpan.FromMilliseconds(1000))
                .ObserveOn(ui)
                .Subscribe(o =>
                {
                    if(ViewModel.Debug.FingerCount <= 2 && ViewModel.State == MainViewState.Navigating)
                    {
                        var angle = Helper.RadianToDegree(Math.Atan2(o.Move.y, o.Move.x));
                        if(!ViewModel.ShowConfig)
                            ViewModel.SelectTile(angle);
                    }
                });

                Dispatcher.BeginInvoke(new Action(() =>
                {
                    Center();
                }));
            }));
        }