Пример #1
0
 /// <inheritdoc/>
 public void CloseAllHiddenWindows()
 {
     foreach (var pane in AvalonDockHelper.GetAllAnchorables(dockingLayoutManager.DockingManager).Where(p => string.IsNullOrEmpty(p.ContentId) && p.IsHidden).ToList())
     {
         CleanEditorPane(pane);
         RemoveEditorPane(pane);
     }
 }
Пример #2
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);
        }
Пример #3
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);
            }
        }
Пример #4
0
        private void ApplyDockingLayout(string text)
        {
            // Save the binding expressions of all the current anchorables
            var bindings             = new Dictionary <string, List <BindingInfo> >();
            var contentIdToBehaviors = new Dictionary <string, Behavior[]>();

            foreach (var anchorable in AvalonDockHelper.GetAllAnchorables(DockingManager).Where(x => !string.IsNullOrEmpty(x.ContentId)))
            {
                var titleBindingInfo     = BindingInfo.FromBindingExpression(BindingOperations.GetBindingExpression(anchorable, LayoutContent.TitleProperty));
                var isVisibleBindingInfo = BindingInfo.FromBindingExpression(BindingOperations.GetBindingExpression(anchorable, AvalonDockHelper.IsVisibleProperty));
                bindings.Add(anchorable.ContentId, new List <BindingInfo> {
                    titleBindingInfo, isVisibleBindingInfo
                });

                // Save behaviors, although complex bindings (eg. nested bindings) will not be restored properly...
                var behaviorCollection = Interaction.GetBehaviors(anchorable);
                if (behaviorCollection.Count > 0)
                {
                    var pendingBehaviours = behaviorCollection.ToArray();
                    behaviorCollection.Clear();
                    contentIdToBehaviors.Add(anchorable.ContentId, pendingBehaviours);
                }
            }

            // Unregister docking manager
            AvalonDockHelper.UnregisterDockingManager(DockingManager);
            // This is a bit of a hack, but we need to do this with AssetPreview due to how bad the LayoutAnchorable is on determining
            // if it's actually visible or not.
            var assetPreviewAnchorable = AvalonDockHelper.GetAllAnchorables(DockingManager).FirstOrDefault(x => string.Equals(x.ContentId, "AssetPreview"));

            if (assetPreviewAnchorable != null)
            {
                gameStudioWindow.UnregisterAssetPreview(assetPreviewAnchorable);
            }

            // Deserialize the string
            using (var stream = new MemoryStream())
            {
                var writer = new StreamWriter(stream);
                writer.Write(text);
                writer.Flush();
                stream.Seek(0, SeekOrigin.Begin);
                var serializer = new XmlLayoutSerializer(DockingManager);
                serializer.Deserialize(stream);
            }

            // Apply saved the binding expressions to the newly deserialized anchorables
            foreach (var anchorable in AvalonDockHelper.GetAllAnchorables(DockingManager).Where(x => !string.IsNullOrEmpty(x.ContentId)))
            {
                List <BindingInfo> bindingInfos;
                if (bindings.TryGetValue(anchorable.ContentId, out bindingInfos))
                {
                    foreach (var bindingInfo in bindingInfos)
                    {
                        BindingOperations.SetBinding(anchorable, bindingInfo.Property, bindingInfo.Binding);
                    }
                }

                if (contentIdToBehaviors.TryGetValue(anchorable.ContentId, out var pendingBehaviours))
                {
                    // Restore behaviors
                    var behaviorCollection = Interaction.GetBehaviors(anchorable);
                    foreach (var b in pendingBehaviours)
                    {
                        b.Attach(anchorable);
                        behaviorCollection.Add(b);
                    }
                }
            }

            // Re-register docking manager with new layout
            AvalonDockHelper.RegisterDockingManager(session.ServiceProvider, DockingManager);
            // Hack: need to get AssetPreview and register handlers again
            assetPreviewAnchorable = AvalonDockHelper.GetAllAnchorables(DockingManager).FirstOrDefault(x => string.Equals(x.ContentId, "AssetPreview"));
            if (assetPreviewAnchorable != null)
            {
                gameStudioWindow.RegisterAssetPreview(assetPreviewAnchorable);
            }
        }