Ejemplo n.º 1
0
        /// <inheritdoc/>
        public void OpenCurveEditorWindow([NotNull] object curve, string name)
        {
            if (curve == null)
            {
                throw new ArgumentNullException(nameof(curve));
            }
            if (dockingLayoutManager == null)
            {
                throw new InvalidOperationException("This method can only be invoked on the IEditorDialogService that has the editor main window as parent.");
            }

            CurveEditorViewModel editorViewModel = null;
            LayoutAnchorable     editorPane      = null;

            if (curveEditor != null)
            {
                // curve editor already exists
                editorViewModel = curveEditor.Item1;
                editorPane      = curveEditor.Item2;
            }

            // Create the editor view model if needed
            if (editorViewModel == null)
            {
                editorViewModel = new CurveEditorViewModel(session.ServiceProvider, session);
            }

            // Populate the editor view model
            if (curve is IComputeCurve <Color4> )
            {
                editorViewModel.AddCurve((IComputeCurve <Color4>)curve, name);
            }
            else if (curve is IComputeCurve <float> )
            {
                editorViewModel.AddCurve((IComputeCurve <float>)curve, name);
            }
            else if (curve is IComputeCurve <Quaternion> )
            {
                editorViewModel.AddCurve((IComputeCurve <Quaternion>)curve, name);
            }
            else if (curve is IComputeCurve <Vector2> )
            {
                editorViewModel.AddCurve((IComputeCurve <Vector2>)curve, name);
            }
            else if (curve is IComputeCurve <Vector3> )
            {
                editorViewModel.AddCurve((IComputeCurve <Vector3>)curve, name);
            }
            else if (curve is IComputeCurve <Vector4> )
            {
                editorViewModel.AddCurve((IComputeCurve <Vector4>)curve, name);
            }

            editorViewModel.Focus();

            // Create the editor pane if needed
            if (editorPane == null)
            {
                editorPane = new LayoutAnchorable
                {
                    Content = new CurveEditorView {
                        DataContext = editorViewModel
                    },
                    Title    = "Curve Editor",
                    CanClose = true,
                };

                editorPane.Closed += CurveEditorClosed;

                //editorPane.Closed += (s, e) =>
                //{
                //    if (((LayoutAnchorable)s).IsHidden)
                //    {
                //        RemoveCurveEditor(true);
                //    }
                //};

                AvalonDockHelper.GetDocumentPane(dockingLayoutManager.DockingManager).Children.Add(editorPane);
            }

            curveEditor = Tuple.Create(editorViewModel, editorPane);

            MakeActiveVisible(editorPane);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Opens (and activates) an editor window for the given asset. If an editor window for this asset already exists, simply activates it.
        /// </summary>
        /// <param name="asset">The asset for which to show an editor window.</param>
        /// <param name="saveSettings">True if <see cref="MRUAdditionalData.OpenedAssets"/> should be updated, false otherwise. Note that if the editor fail to load it will not be updated.</param>
        /// <returns></returns>
        internal async Task OpenAssetEditorWindow([NotNull] AssetViewModel asset, bool saveSettings)
        {
            if (asset == null)
            {
                throw new ArgumentNullException(nameof(asset));
            }
            if (dockingLayoutManager == null)
            {
                throw new InvalidOperationException("This method can only be invoked on the IEditorDialogService that has the editor main window as parent.");
            }

            // Switch to the editor layout before adding any Pane
            if (assetEditors.Count == 0)
            {
                dockingLayoutManager.SwitchToEditorLayout();
            }

            using (await mutex.LockAsync())
            {
                LayoutAnchorable editorPane = null;
                IEditorView      view;
                // Asset already has an editor?
                if (asset.Editor != null)
                {
                    // Look for the corresponding pane
                    if (!assetEditors.TryGetValue(asset.Editor, out editorPane))
                    {
                        // Inconsistency, clean leaking editor
                        RemoveAssetEditor(asset);
                        // Try to find if another editor currently has this asset
                        var editor = assetEditors.Keys.OfType <IMultipleAssetEditorViewModel>().FirstOrDefault(x => x.OpenedAssets.Contains(asset));
                        if (editor != null)
                        {
                            editorPane   = assetEditors[editor];
                            asset.Editor = editor;
                        }
                    }
                }
                // Existing editor?
                if (editorPane != null)
                {
                    // Make the pane visible immediately
                    MakeActiveVisible(editorPane);
                    view = editorPane.Content as IEditorView;
                    if (view?.EditorInitialization != null)
                    {
                        // Wait for the end of the initialization
                        await view.EditorInitialization;
                    }
                    return;
                }

                // Create a new editor view
                view = asset.ServiceProvider.Get <IAssetsPluginService>().ConstructEditionView(asset);
                if (view != null)
                {
                    // Pane may already exists (e.g. created from layout saving)
                    editorPane = AvalonDockHelper.GetAllAnchorables(dockingLayoutManager.DockingManager).FirstOrDefault(p => p.Title == asset.Url);
                    if (editorPane == null)
                    {
                        editorPane = new LayoutAnchorable {
                            CanClose = true
                        };
                        // Stack the asset in the dictionary of editor to prevent double-opening while double-clicking twice on the asset, since the initialization is async
                        AvalonDockHelper.GetDocumentPane(dockingLayoutManager.DockingManager).Children.Add(editorPane);
                    }
                    editorPane.IsActiveChanged   += EditorPaneIsActiveChanged;
                    editorPane.IsSelectedChanged += EditorPaneIsSelectedChanged;
                    editorPane.Closing           += EditorPaneClosing;
                    editorPane.Closed            += EditorPaneClosed;
                    editorPane.Content            = view;
                    // Make the pane visible immediately
                    MakeActiveVisible(editorPane);
                    // Initialize the editor view
                    view.DataContext = asset;

                    // Create a binding for the title
                    var binding = new Binding(nameof(AssetViewModel.Url))
                    {
                        Mode = BindingMode.OneWay, Source = asset
                    };
                    BindingOperations.SetBinding(editorPane, LayoutContent.TitleProperty, binding);

                    var viewModel = await view.InitializeEditor(asset);

                    if (viewModel == null)
                    {
                        // Could not initialize editor
                        CleanEditorPane(editorPane);
                        RemoveEditorPane(editorPane);
                    }
                    else
                    {
                        assetEditors[viewModel] = editorPane;
                        openedAssets.Add(asset);
                        var multiEditor = viewModel as IMultipleAssetEditorViewModel;
                        if (multiEditor != null)
                        {
                            foreach (var item in multiEditor.OpenedAssets)
                            {
                                if (item.Editor != null)
                                {
                                    // Note: this could happen in some case after undo/redo that involves parenting of scenes
                                    RemoveAssetEditor(item);
                                }
                                item.Editor = viewModel;
                            }
                            multiEditor.OpenedAssets.CollectionChanged += (_, e) => MultiEditorOpenAssetsChanged(multiEditor, e);
                        }
                        else
                        {
                            asset.Editor = viewModel;
                        }
                    }
                }
            }

            // If the opening of the editor failed, go back to normal layout
            if (assetEditors.Count == 0)
            {
                dockingLayoutManager.SwitchToNormalLayout();
                return;
            }

            if (saveSettings)
            {
                dockingLayoutManager.SaveOpenAssets(OpenedAssets);
            }
        }