Skip to content

Commit

Permalink
DYN-5862 Python editor docking improvements (DynamoDS#13984)
Browse files Browse the repository at this point in the history
* Python docking improvements

* Update resources

* update

* Update ScriptEditorWindow.xaml.cs

* update CachedEngine when editor engine is changed in docked state

* Improvement python editor behavior inside a custom node.

* Update DynamoViewModel.cs

* Addressing comments

* Update PythonNode.cs
  • Loading branch information
reddyashish authored and Enzo707 committed May 22, 2023
1 parent 28915a1 commit ebe6c31
Show file tree
Hide file tree
Showing 18 changed files with 298 additions and 164 deletions.
4 changes: 2 additions & 2 deletions src/DynamoCoreWpf/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/DynamoCoreWpf/Properties/Resources.en-US.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2143,7 +2143,7 @@ Do you want to install the latest Dynamo update?</value>
<value>Write note here</value>
</data>
<data name="SideBarPanelViewTitle" xml:space="preserve">
<value>SideBar Panel</value>
<value>Sidebar</value>
</data>
<data name="ExtensionAdded" xml:space="preserve">
<value>Extension tab added to the extensions side bar.</value>
Expand Down
2 changes: 1 addition & 1 deletion src/DynamoCoreWpf/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2367,7 +2367,7 @@ Want to publish a different package?</value>
<value>Write note here</value>
</data>
<data name="SideBarPanelViewTitle" xml:space="preserve">
<value>SideBar Panel</value>
<value>Sidebar</value>
</data>
<data name="ExtensionAdded" xml:space="preserve">
<value>Extension tab added to the extensions side bar.</value>
Expand Down
4 changes: 2 additions & 2 deletions src/DynamoCoreWpf/UI/GuidedTour/GuidesValidationMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -577,14 +577,14 @@ internal static void ExecuteViewDetailsSideBar(Step stepInfo, StepUIAutomation u
if (packageDetailsWindow == null)
return;
//In order to close the Package Details tab we need first to get the Tab, then get the Close button and finally call the event to close it
TabItem tabitem = dynamoView.SideBarPanelTabItems.OfType<TabItem>().SingleOrDefault(n => n.Header.ToString() == packageDetailsName);
TabItem tabitem = stepInfo.DynamoViewModelStep.SideBarTabItems.OfType<TabItem>().SingleOrDefault(n => n.Header.ToString() == packageDetailsName);
if (tabitem == null)
return;
//Get the Close button from the PackageDetailsView
Button closeButton = GuideUtilities.FindChild(tabitem, closeButtonName) as Button;
if (closeButton == null)
return;
dynamoView.OnCloseRightSidePanelTab(closeButton, null);
dynamoView.OnCloseRightSideBarTab(closeButton, null);
}
}

Expand Down
78 changes: 74 additions & 4 deletions src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Media;
using System.Windows.Threading;
Expand Down Expand Up @@ -42,6 +43,8 @@
using Dynamo.Wpf.ViewModels.FileTrust;
using Dynamo.Wpf.ViewModels.Watch3D;
using DynamoUtilities;
using ICSharpCode.AvalonEdit;
using PythonNodeModels;
using ISelectable = Dynamo.Selection.ISelectable;
using WpfResources = Dynamo.Wpf.Properties.Resources;

Expand All @@ -63,24 +66,40 @@ public partial class DynamoViewModel : ViewModelBase, IDynamoViewModel

// Can the user run the graph
private bool CanRunGraph => HomeSpace.RunSettings.RunEnabled && !HomeSpace.GraphRunInProgress;

private ObservableCollection<DefaultWatch3DViewModel> watch3DViewModels = new ObservableCollection<DefaultWatch3DViewModel>();
private ObservableCollection<TabItem> sideBarTabItems = new ObservableCollection<TabItem>();

/// <summary>
/// An observable collection of workspace view models which tracks the model
/// An observable collection of workspace view models which tracks the model.
/// </summary>
private ObservableCollection<WorkspaceViewModel> workspaces = new ObservableCollection<WorkspaceViewModel>();

/// <summary>
/// Set of node window id's that are currently docked in right side sidebar
/// Set of node window id's that are currently docked in right side sidebar.
/// </summary>
internal HashSet<string> CurrentDockedWindows { get; set; } = new HashSet<string>();
internal HashSet<string> DockedNodeWindows { get; set; } = new HashSet<string>();

/// <summary>
/// Node window's state, either DockRight or FloatingWindow.
/// </summary>
internal Dictionary<string, ViewExtensionDisplayMode> NodeWindowsState { get; set; } = new Dictionary<string, ViewExtensionDisplayMode>();

/// <summary>
/// Collection of Right SideBar tab items: view extensions and docked windows.
/// </summary>
public ObservableCollection<TabItem> SideBarTabItems
{
get
{
return sideBarTabItems;
}
set
{
sideBarTabItems = value;
RaisePropertyChanged(nameof(SideBarTabItems));
}
}

public ObservableCollection<WorkspaceViewModel> Workspaces
{
get { return workspaces; }
Expand Down Expand Up @@ -1470,6 +1489,57 @@ internal void AddToRecentFiles(string path)
}
}

// Get the nodemodel if a node is present in any open workspace.
internal NodeModel GetDockedWindowNodeModel(string tabId)
{
var workspaces = Model.Workspaces;
NodeModel nodeModel = null;

foreach (WorkspaceModel workspace in workspaces)
{
nodeModel = workspace.Nodes.FirstOrDefault(x => x.GUID.ToString() == tabId);
if (nodeModel != null)
{
return nodeModel;
}
}
return nodeModel;
}

/// <summary>
/// Closes any docked python script windows if there are no unsaved changes.
/// Show warning message on the script editor if it has unsaved changes.
/// </summary>
/// <param name="nodes">Nodes in the workspace</param>
internal bool CanCloseDockedNodeWindows(ObservableCollection<NodeViewModel> nodes)
{
foreach (var node in nodes)
{
var id = node.NodeModel.GUID.ToString();
if (DockedNodeWindows.Contains(id))
{
var tabItem = SideBarTabItems.OfType<TabItem>().SingleOrDefault(n => n.Uid.ToString() == id);
NodeModel nodeModel = GetDockedWindowNodeModel(tabItem.Uid);

if (nodeModel is PythonNode pythonNode)
{
var editor = (tabItem.Content as Grid).ChildOfType<TextEditor>();
if (editor != null && editor.IsModified)
{
pythonNode.OnWarnUserScript();
tabItem.Focus();
return false;
}
pythonNode.Dispose();
}

SideBarTabItems.Remove(tabItem);
DockedNodeWindows.Remove(id);
}
}
return true;
}

/// <summary>
/// Returns the file-save dialog with customized file types of Dynamo.
/// </summary>
Expand Down
10 changes: 8 additions & 2 deletions src/DynamoCoreWpf/ViewModels/Core/WorkspaceViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1329,8 +1329,14 @@ private void Hide(object parameters)
}
else
{
if (!Model.HasUnsavedChanges || DynamoViewModel.AskUserToSaveWorkspaceOrCancel(Model))
DynamoViewModel.Model.RemoveWorkspace(Model);
// Close the custom workspace only if all docked node windows are saved and can be closed.
if (DynamoViewModel.CanCloseDockedNodeWindows(Nodes))
{
if (!Model.HasUnsavedChanges || DynamoViewModel.AskUserToSaveWorkspaceOrCancel(Model))
{
DynamoViewModel.Model.RemoveWorkspace(Model);
}
}
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/DynamoCoreWpf/Views/Core/DynamoView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -1556,7 +1556,7 @@
Grid.Row="2"
Grid.Column="4"
Grid.RowSpan="2">
<TabControl Name="tabDynamic" Background="#353535" BorderThickness="0" ItemsSource="{Binding}">
<TabControl Name="tabDynamic" Background="#353535" BorderThickness="0" ItemsSource="{Binding SideBarTabItems, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
<TabControl.Resources>
<!--Styling for the close button in the tab-->
<Style TargetType="{x:Type Button}"
Expand Down Expand Up @@ -1594,11 +1594,11 @@
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Header}"
FontFamily="{StaticResource ArtifaktElementBold}"
FontSize="12"
Margin="5,5,0,0"
Margin="5,7,0,0"
HorizontalAlignment="Stretch"/>

<!--Button to close a particular tab-->
<Button Name="CloseButton" Style="{StaticResource CloseButtonStyle}" DockPanel.Dock="Right" Click="OnCloseRightSidePanelTab"
<Button Name="CloseButton" Style="{StaticResource CloseButtonStyle}" DockPanel.Dock="Right" Click="OnCloseRightSideBarTab"
Margin="5,5,5,0" Uid="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Uid}">
<Image Width="18" Height="18" HorizontalAlignment="Right" VerticalAlignment="Center">
<Image.Style>
Expand All @@ -1618,7 +1618,7 @@
</Image>
</Button>
<!-- Undock -->
<Button Name="UndockButton" Style="{StaticResource CloseButtonStyle}" DockPanel.Dock="Right" Click="OnUndockRightSidePanelTab"
<Button Name="UndockButton" Style="{StaticResource CloseButtonStyle}" DockPanel.Dock="Right" Click="OnUndockRightSideBarTab"
Margin="8,5,0,0" Uid="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Uid}">
<Image Width="18" Height="18" HorizontalAlignment="Right" VerticalAlignment="Center">
<Image.Style>
Expand Down
Loading

0 comments on commit ebe6c31

Please sign in to comment.