Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DocumentationBrowserViewExtension Upgrade + Insert #13414

Merged
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
263c0ce
Stylesheet Update
dnenov Sep 25, 2022
11c1ee3
HtmlGenerator Structure Change
dnenov Sep 25, 2022
bd5ab74
Markdown Moved
dnenov Sep 26, 2022
3d1acd7
Input Output Table Style Update
dnenov Sep 27, 2022
5aa8df5
Inputs Outputs Tables Finished
dnenov Sep 27, 2022
5ff399e
Body Style Changes
dnenov Sep 27, 2022
4dc5d89
Image Navigation Started
dnenov Oct 4, 2022
77fa947
Breadcrumbs ILayoutSpecSource Implementation, Image Navigation
dnenov Oct 6, 2022
12edda3
Image Navigation Styling
dnenov Oct 10, 2022
987cab2
Insert Functionality Started
dnenov Oct 10, 2022
ea167c1
Insert Functionality Working with JSON Graphs
dnenov Oct 17, 2022
98f60fd
Dynamo Graph from MD File Location
dnenov Oct 17, 2022
14274f8
DissolveNestedGroups Command Added, Multiple Changes to Documentation…
dnenov Oct 18, 2022
69f419d
Insert WIP
dnenov Oct 20, 2022
aaf268d
Dyf | Dyn Split
dnenov Oct 21, 2022
553499c
Removed Prompt to Save File
dnenov Oct 21, 2022
3453637
Toast Notifications Added
dnenov Oct 21, 2022
2b140c3
Note Alignment Fix
dnenov Oct 25, 2022
ce6f658
Initial Tests Added
dnenov Oct 25, 2022
31a0997
Merge remote-tracking branch 'upstream/master' into dnenov-update-doc…
dnenov Oct 25, 2022
e357f7f
Image Controls - Visual Bump
dnenov Oct 26, 2022
24d96e9
Tests Added
dnenov Oct 26, 2022
8fec1b8
Localization for DocumnationBrowser Added
dnenov Oct 26, 2022
ae41083
Merge remote-tracking branch 'upstream/master' into dnenov-update-doc…
dnenov Oct 28, 2022
7d57a62
Localization Issues Fallback Folder
dnenov Oct 28, 2022
a3b1a9a
Test Fix 1
dnenov Oct 28, 2022
192e221
Test Fix 2
dnenov Oct 28, 2022
227aa53
Test Fix 3
dnenov Oct 28, 2022
5c9674c
Comments and Fixes
dnenov Oct 28, 2022
ecc5159
RunSettings Tooltips Changes
dnenov Oct 29, 2022
9f18653
Toast Notificaiton from DynamoModel to DynamoViewModel
dnenov Oct 30, 2022
2f7a2a9
Unsubscribe RequestNotification
dnenov Oct 30, 2022
7e9d00a
Mk2Html Whitlisting CSS Properties Added
dnenov Oct 31, 2022
16fc325
Comments
dnenov Oct 31, 2022
b4e18bc
Comments
dnenov Oct 31, 2022
171249c
Test Fix
dnenov Nov 1, 2022
0d4d6f6
Merge branch 'master' of https://github.com/DynamoDS/Dynamo into dnen…
dnenov Nov 1, 2022
2dd0d8e
Comments
dnenov Nov 1, 2022
14bd9d8
Comments
dnenov Nov 1, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
356 changes: 251 additions & 105 deletions src/DocumentationBrowserViewExtension/Docs/MarkdownStyling.html

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Dynamo.Utilities;
using Dynamo.Utilities;
using System.IO;
using System.Reflection;

Expand All @@ -17,7 +17,14 @@ internal static string GetDPIScript()
{
return ResourceUtilities.DPISCRIPT;
}

/// <summary>
/// Returns the Image Navigation Script
/// </summary>
/// <returns></returns>
internal static string GetImageNavigationScript()
{
return ResourceUtilities.IMGNAVIGATIONSCRIPT;
}
/// <summary>
/// Returns the content of an embedded resource file.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Dynamo.Logging;
using Dynamo.Logging;
using Dynamo.Utilities;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Wpf;
Expand Down Expand Up @@ -113,6 +113,7 @@ protected virtual void Dispose(bool disposing)
this.documentationBrowser.Dispose();
}
this.documentationBrowser.DpiChanged -= DocumentationBrowser_DpiChanged;
this.documentationBrowser.CoreWebView2.WebMessageReceived -= CoreWebView2OnWebMessageReceived;
}

async void InitializeAsync()
Expand All @@ -138,6 +139,18 @@ async void InitializeAsync()
{
this.documentationBrowser.NavigateToString(htmlContent);
}));

this.documentationBrowser.CoreWebView2.WebMessageReceived += CoreWebView2OnWebMessageReceived;
}

private void CoreWebView2OnWebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
{
var message = e.TryGetWebMessageAsString();
if (string.Equals(message, "insert"))
{
// Insert the graph inside the current worskspace
this.viewModel.InsertGraph();
}
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,37 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Security.Permissions;
using System.Web.UI.WebControls;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using DesignScript.Builtin;
using Dynamo.Configuration;
using Dynamo.Core;
using Dynamo.DocumentationBrowser.Properties;
using Dynamo.Graph;
using Dynamo.Graph.Workspaces;
using Dynamo.Logging;
using Dynamo.Selection;
using Dynamo.Models;
using Dynamo.PackageManager;
using Dynamo.ViewModels;
using Dynamo.Wpf.Extensions;
using Dynamo.Wpf.Interfaces;
using MenuItem = System.Windows.Controls.MenuItem;

namespace Dynamo.DocumentationBrowser
{
/// <summary>
/// The DocumentationBrowser view extension displays web or local html files on the Dynamo right panel.
/// It reacts to documentation display request events in Dynamo to know what and when to display documentation.
/// </summary>
public class DocumentationBrowserViewExtension : ViewExtensionBase, IViewExtension, ILogSource
public class DocumentationBrowserViewExtension : ViewExtensionBase, IViewExtension, ILogSource, ILayoutSpecSource
{
private ViewStartupParams viewStartupParamsReference;
private ViewLoadedParams viewLoadedParamsReference;
private MenuItem documentationBrowserMenuItem;
private PackageManagerExtension pmExtension;
Expand All @@ -27,8 +40,11 @@ public class DocumentationBrowserViewExtension : ViewExtensionBase, IViewExtensi
internal DirectoryInfo fallbackDocPath;
internal DirectoryInfo webBrowserUserDataFolder;

internal Dictionary<string, string> BreadCrumbsDict { get; set; }

internal DocumentationBrowserView BrowserView { get; private set; }
internal DocumentationBrowserViewModel ViewModel { get; private set; }
private DynamoViewModel DynamoViewModel { get; set; }

/// <summary>
/// Extension Name
Expand Down Expand Up @@ -59,8 +75,20 @@ internal void OnMessageLogged(ILogMessage msg)

#region IViewExtension lifecycle

private Func<LayoutSpecification> layouthandler;

public event Action<string> RequestApplyLayoutSpec;
dnenov marked this conversation as resolved.
Show resolved Hide resolved

public event Func<LayoutSpecification> RequestLayoutSpec
{
add { layouthandler += value; }
remove { layouthandler -= value; }
}

public override void Startup(ViewStartupParams viewStartupParams)
{
this.viewStartupParamsReference = viewStartupParams;

pmExtension = viewStartupParams.ExtensionManager.Extensions.OfType<PackageManagerExtension>().FirstOrDefault();
PackageDocumentationManager.Instance.AddDynamoPaths(viewStartupParams.PathManager);

Expand Down Expand Up @@ -101,11 +129,12 @@ public override void Startup(ViewStartupParams viewStartupParams)
public override void Loaded(ViewLoadedParams viewLoadedParams)
{
if (viewLoadedParams == null) throw new ArgumentNullException(nameof(viewLoadedParams));
this.viewLoadedParamsReference = viewLoadedParams;

this.ViewModel.MessageLogged += OnViewModelMessageLogged;
this.ViewModel.HandleInsertFile += OnInsertFile;
PackageDocumentationManager.Instance.MessageLogged += OnMessageLogged;

this.viewLoadedParamsReference = viewLoadedParams;

// Add a button to Dynamo View menu to manually show the window
this.documentationBrowserMenuItem = new MenuItem { Header = Resources.MenuItemText, IsCheckable = true };
Expand All @@ -132,8 +161,173 @@ public override void Loaded(ViewLoadedParams viewLoadedParams)
{
OnPackageLoaded(pkg);
}

this.DynamoViewModel = (viewLoadedParams.DynamoWindow.DataContext as DynamoViewModel);
}

private void OnInsertFile(object sender, InsertDocumentationLinkEventArgs e)
{
if (DynamoViewModel.Model.CurrentWorkspace.GetType() == typeof(HomeWorkspaceModel))
dnenov marked this conversation as resolved.
Show resolved Hide resolved
{
var homeWorkspace = DynamoViewModel.Model.CurrentWorkspace as HomeWorkspaceModel;
if (homeWorkspace != null && homeWorkspace.RunSettings.RunType != RunType.Manual)
{
DynamoViewModel.MainGuideManager.CreateRealTimeInfoWindow("Example file added to workspace. Run mode changed to Manual.", true);
dnenov marked this conversation as resolved.
Show resolved Hide resolved
homeWorkspace.RunSettings.RunType = RunType.Manual;
}
}

var existingGroups = GetExistingGroups();

// Insert the file and select all the elements that were inserted
this.DynamoViewModel.Model.InsertFileFromPath(e.Data);

if (!DynamoSelection.Instance.Selection.Any()) return;
DoEvents();

GroupInsertedGraph(existingGroups, e.Name);
DoEvents();

// We have selected all the nodes and notes from the inserted graph
// Now is the time to auto layout the inserted nodes
this.DynamoViewModel.GraphAutoLayoutCommand.Execute(null);
DoEvents();

this.DynamoViewModel.FitViewCommand.Execute(null);
DoEvents();
}


private void GroupInsertedGraph(List<AnnotationViewModel> existingGroups, string graphName)
{
var selection = GetCurrentSelection();
var hostGroups = GetAllHostingGroups(existingGroups);

foreach (var group in hostGroups)
{
group.DissolveNestedGroupsCommand.Execute(null);
}


foreach (var group in hostGroups)
{
selection.RemoveAll(x => group.AnnotationModel.ContainsModel(x as ModelBase));
}

DynamoSelection.Instance.Selection.AddRange(selection);
DynamoSelection.Instance.Selection.AddRange(hostGroups.Select(x => x.AnnotationModel));
DoEvents();

var annotation = this.DynamoViewModel.Model.CurrentWorkspace.AddAnnotation("Inserted Dynamo graph", Guid.NewGuid());
annotation.AnnotationText = graphName;
DoEvents();

var annotationViewModel = DynamoViewModel.CurrentSpaceViewModel.Annotations
.First(x => x.AnnotationModel == annotation);

// Is that the correct way of getting a GroupStyleItem from StyleItem?
dnenov marked this conversation as resolved.
Show resolved Hide resolved
var styleItem = annotationViewModel.GroupStyleList.First(x => x.Name.Equals("Review"));
dnenov marked this conversation as resolved.
Show resolved Hide resolved
var groupStyleItem = new GroupStyleItem {Name = styleItem.Name, HexColorString = styleItem.HexColorString};
annotationViewModel.UpdateGroupStyle(groupStyleItem);

DynamoSelection.Instance.ClearSelection();
DynamoSelection.Instance.Selection.AddRange(annotation.Nodes);
DoEvents();
}

private List<AnnotationViewModel> GetAllHostingGroups(List<AnnotationViewModel> existingGroups)
{
List<AnnotationViewModel> hostGroups = new List<AnnotationViewModel>();

foreach (var group in this.DynamoViewModel.CurrentSpaceViewModel.Annotations)
{
if (existingGroups.Contains(group)) continue;

if (group.AnnotationModel.HasNestedGroups)
{
hostGroups.Add(group);
}
}

return hostGroups;
}

private List<ISelectable> GetCurrentSelection()
{
List<ISelectable> selection = new List<ISelectable>();

foreach (var selected in DynamoSelection.Instance.Selection)
{
selection.Add(selected);
}

return selection;
}
private List<AnnotationViewModel> GetExistingGroups()
{
List<AnnotationViewModel> result = new List<AnnotationViewModel>();

foreach (var group in this.DynamoViewModel.CurrentSpaceViewModel.Annotations)
{
result.Add(group);
}

return result;
}

private void RequestLoadLayoutSpecs()
{
if (BreadCrumbsDict != null) return;

var output = layouthandler?.Invoke();
if (output == null) return;

PopulateBreadCrumbsDictionary(output);
}

private void PopulateBreadCrumbsDictionary(LayoutSpecification layoutSpec)
{
var section = layoutSpec.sections.First();
var breadCrumb = string.Empty;

BreadCrumbsDict = new Dictionary<string, string>();

if (section.childElements.Count == 0) return;

foreach (var child in section.childElements)
{
breadCrumb = child.text + " / ";

RecursiveIncludeSearch(child, breadCrumb);
}

this.ViewModel.BreadCrumbsDictionary = BreadCrumbsDict;
}

private void RecursiveIncludeSearch(LayoutElement child, string breadCrumb)
{
string crumb = breadCrumb;

if (child.childElements.Any())
{
foreach (var grandchild in child.childElements)
{
crumb = breadCrumb + grandchild.text + " / ";

RecursiveIncludeSearch(grandchild, crumb);
}
}

foreach (var info in child.include)
{
var typeArray = info.path.Split('.');
var type = typeArray[typeArray.Length - 2] + "." + typeArray[typeArray.Length - 1];

BreadCrumbsDict[type] = crumb.Remove(crumb.Length-3);
}
}


private void OnPackageLoaded(Package pkg)
{
// Add documentation files from the package to the DocManager
Expand All @@ -147,6 +341,7 @@ private void MenuItemUnCheckedHandler(object sender, RoutedEventArgs e)

private void MenuItemCheckHandler(object sender, RoutedEventArgs e)
{

AddToSidebar(true);
}

Expand All @@ -161,6 +356,7 @@ protected virtual void Dispose(bool disposing)
if (this.ViewModel != null)
{
this.ViewModel.MessageLogged -= OnViewModelMessageLogged;
this.ViewModel.HandleInsertFile -= OnInsertFile;
}

if (this.documentationBrowserMenuItem != null)
Expand Down Expand Up @@ -209,6 +405,9 @@ public void HandleRequestOpenDocumentationLink(OpenDocumentationLinkEventArgs ar
if (args.IsRemoteResource)
return;

// make sure the breadcrumbs dictionary has been loaded
RequestLoadLayoutSpecs();

// make sure the view is added to the Sidebar
// this also forces the Sidebar to open
AddToSidebar(false);
Expand Down Expand Up @@ -263,5 +462,33 @@ public override void Closed()
this.documentationBrowserMenuItem.IsChecked = false;
}
}

#region helper methods

/// <summary>
/// Force the Dispatcher to empty it's queue
/// </summary>
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public static void DoEvents()
{
var frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background,
new DispatcherOperationCallback(ExitFrame), frame);
Dispatcher.PushFrame(frame);
}

/// <summary>
/// Helper method for DispatcherUtil
/// </summary>
/// <param name="frame"></param>
/// <returns></returns>
private static object ExitFrame(object frame)
{
((DispatcherFrame)frame).Continue = false;
return null;
}

#endregion

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<Project>{B5F435CB-0D8A-40B1-A4F7-5ECB3CE792A9}</Project>
<Name>DynamoUtilities</Name>
</ProjectReference>
<ProjectReference Include="..\LibraryViewExtensionMSWebBrowser\LibraryViewExtensionMSWebBrowser.csproj" />
dnenov marked this conversation as resolved.
Show resolved Hide resolved
<ProjectReference Include="..\NodeServices\DynamoServices.csproj">
<Project>{ef879a10-041d-4c68-83e7-3192685f1bae}</Project>
<Name>DynamoServices</Name>
Expand Down Expand Up @@ -96,9 +97,6 @@
<ItemGroup>
<None Include="README.md" />
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Docs\IntegerOverflow.html" />
</ItemGroup>
Expand Down
Loading