Skip to content

Commit

Permalink
Added 'Open View' component.
Browse files Browse the repository at this point in the history
  • Loading branch information
kike-garbo committed Dec 5, 2023
1 parent 8d4aa72 commit 2905072
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 6 deletions.
2 changes: 2 additions & 0 deletions docs/pages/_en/1.0/reference/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ group: Deployment & Configs

### RC

- Added 'Open View' component.

{% endcapture %}
{% include ltr/release_header_next.html title="Upcoming Changes" note=rc_release_notes %}

Expand Down
21 changes: 18 additions & 3 deletions src/RhinoInside.Revit.External/DB/Extensions/Document.cs
Original file line number Diff line number Diff line change
Expand Up @@ -998,12 +998,17 @@ public static View GetActiveGraphicalView(this Document doc)
}

/// <summary>
/// Sets the active Graphical <see cref="Autodesk.Revit.DB.View"/> of the provided <see cref="Autodesk.Revit.DB.Document"/>.
/// Sets the active <see cref="Autodesk.Revit.DB.View"/> of the provided <see cref="Autodesk.Revit.DB.Document"/>.
/// </summary>
/// <param name="doc"></param>
/// <param name="view">View to be activated</param>
public static bool SetActiveGraphicalView(this Document document, View view) =>
SetActiveGraphicalView(document, view, out var _);
public static bool SetActiveView(this Document document, View view)
{
if (view is null)
throw new ArgumentNullException(nameof(view));

return SetActiveView(document, view, out var _);
}

/// <summary>
/// Sets the active Graphical <see cref="Autodesk.Revit.DB.View"/> of the provided <see cref="Autodesk.Revit.DB.Document"/>.
Expand All @@ -1018,6 +1023,16 @@ public static bool SetActiveGraphicalView(this Document document, View view, out
if (!view.IsGraphicalView())
throw new ArgumentException("Input view is not a graphical view.", nameof(view));

return SetActiveView(document, view, out wasOpened);
}

/// <summary>
/// Sets the active Graphical <see cref="Autodesk.Revit.DB.View"/> of the provided <see cref="Autodesk.Revit.DB.Document"/>.
/// </summary>
/// <param name="doc"></param>
/// <param name="view">View to be activated</param>
private static bool SetActiveView(this Document document, View view, out bool wasOpened)
{
if (!document.Equals(view.Document))
throw new ArgumentException("View does not belong to the specified document", nameof(view));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public override UIDocument ActiveUIDocument
if (value.TryGetActiveGraphicalView(out var uiView))
{
HostedApplication.Active.InvokeInHostContext
(() => value.Document.SetActiveGraphicalView(value.Document.GetElement(uiView.ViewId) as View));
(() => value.Document.SetActiveGraphicalView(value.Document.GetElement(uiView.ViewId) as View, out var _));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ protected override void AfterSolveInstance()
{
base.AfterSolveInstance();

ActiveView?.Document.SetActiveGraphicalView(ActiveView);
ActiveView?.Document.SetActiveView(ActiveView);
ActiveView = default;

if (ViewsToClose.Count > 0)
Expand Down
2 changes: 1 addition & 1 deletion src/RhinoInside.Revit.GH/Components/Topology/AddSpace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ protected override void AfterSolveInstance()
{
base.AfterSolveInstance();

ActiveView?.Document.SetActiveGraphicalView(ActiveView);
ActiveView?.Document.SetActiveView(ActiveView);
ActiveView = default;

foreach (var view in (ViewsToClose as IEnumerable<ARDB.View>).Reverse())
Expand Down
169 changes: 169 additions & 0 deletions src/RhinoInside.Revit.GH/Components/Views/Open.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Parameters;
using Grasshopper.Kernel.Types;
using RhinoInside.Revit.External.DB.Extensions;
using ARDB = Autodesk.Revit.DB;
using ARUI = Autodesk.Revit.UI;

namespace RhinoInside.Revit.GH.Components.Views
{
[ComponentVersion(introduced: "1.18")]
public class ViewOpen : ZuiComponent
{
public override Guid ComponentGuid => new Guid("E13FC388-D607-4A62-BEBC-498A9445F91A");
public override GH_Exposure Exposure => GH_Exposure.primary;
protected override string IconTag => string.Empty;

public ViewOpen() : base
(
name: "Open View",
nickname: "V-Open",
description: "Open-Close a Revit view",
category: "Revit",
subCategory: "View"
)
{ }

protected override ParamDefinition[] Inputs => inputs;
static readonly ParamDefinition[] inputs =
{
ParamDefinition.Create<Parameters.View>("View", "V", string.Empty),
ParamDefinition.Create<Param_Boolean>("Open", "O", string.Empty, optional: true, relevance: ParamRelevance.Primary)
};

protected override ParamDefinition[] Outputs => outputs;
static readonly ParamDefinition[] outputs =
{
ParamDefinition.Create<Parameters.View>("View", "V", string.Empty),
ParamDefinition.Create<Param_Boolean>("Open", "O", string.Empty, optional: true, relevance: ParamRelevance.Primary)
};

private readonly Dictionary<Types.View, bool> ViewStates = new Dictionary<Types.View, bool>();
protected override void BeforeSolveInstance()
{
base.BeforeSolveInstance();
}

protected override void TrySolveInstance(IGH_DataAccess DA)
{
if (!Params.TryGetData(DA, "View", out Types.View view, x => x.IsValid)) return;
else Params.TrySetData(DA, "View", () => view);
if (!Params.TryGetData(DA, "Open", out bool? open)) return;

var isOpen = view.Value.IsOpen();
if (open is object)
{
if (view.Value.IsTemplate && open is true)
AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"Can't open view template '{view.DisplayName}'");
else if (view.Value.IsCallout && open is true)
AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"Can't open callout view'{view.DisplayName}'");
else
ViewStates[view] = open.Value;
}

Params.TrySetData(DA, "Open", () => isOpen);
}

protected override void AfterSolveInstance()
{
if (ViewStates.Count > 0)
{
try
{
Guest.Instance.CommitTransactionGroups();
var activeView = Revit.ActiveUIDocument.ActiveView;

try
{
foreach (var group in ViewStates.GroupBy(x => x.Key.Document))
{
using (var uiDocument = new ARUI.UIDocument(group.Key))
{
var openViews = uiDocument.GetOpenUIViews();
if (openViews.Count == 0)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"Document {uiDocument.Document.GetTitle()} is not open on UI.");
}
else
{
var openViewIds = new HashSet<ARDB.ElementId>(openViews.Select(x => x.ViewId));
var viewsToClose = group.Where(x => x.Value == false).Select(x => x.Key);
var viewsToOpen = group.Where(x => x.Value == true).Select(x => x.Key);

foreach (var view in viewsToOpen)
{
if (!openViewIds.Contains(view.Id))
view.Value.Document.SetActiveView(view.Value);
}

foreach (var view in viewsToClose)
{
if (view.Value.IsEquivalent(activeView))
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"Can't close '{view.DisplayName}' because is the active one.");
}
else
{
try { view.Value.Close(); }
catch (Exception e) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.Message); }
}
}
}
}
}
}
finally
{
activeView.Document.SetActiveView(activeView);
}

// Reconstruct output 'Open' with final values from 'View'.
var _View_ = Params.IndexOfOutputParam("View");
var _Open_ = Params.IndexOfOutputParam("Open");
if (_View_ >= 0 && _Open_ >= 0)
{
var viewParam = Params.Output[_View_];
var openParam = Params.Output[_Open_];
var openData = new GH_Structure<GH_Boolean>();

var viewData = viewParam.VolatileData;
foreach (var path in viewData.Paths)
{
var open = viewData.get_Branch(path).Cast<object>().Select(x => (x as Types.View)?.Value.IsOpen());
openData.AppendRange(open.Select(x => x.HasValue ? new GH_Boolean(x.Value) : null), path);
}

openParam.ClearData();
openParam.AddVolatileDataTree(openData);
}
}
finally
{
ViewStates.Clear();
Guest.Instance.StartTransactionGroups();
}
}

base.AfterSolveInstance();
}

#region UI
protected override void AppendAdditionalComponentMenuItems(ToolStripDropDown menu)
{
base.AppendAdditionalComponentMenuItems(menu);

var activeApp = Revit.ActiveUIApplication;
#if REVIT_2019
menu.AppendPostableCommand(ARUI.PostableCommand.CloseInactiveViews, "Close Inactive Views…");
menu.AppendPostableCommand(ARUI.PostableCommand.TabViews, "Tab Views…");
menu.AppendPostableCommand(ARUI.PostableCommand.TileViews, "Tile Views…");
#endif
}
#endregion
}
}
1 change: 1 addition & 0 deletions src/RhinoInside.Revit.GH/RhinoInside.Revit.GH.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@
<Compile Include="Components\Views\Graphics\GraphicOverrides.cs" />
<Compile Include="Components\Views\Graphics\WorksetVisibilityOverrides.cs" />
<Compile Include="Components\Views\Identity.cs" />
<Compile Include="Components\Views\Open.cs" />
<Compile Include="Components\Views\QueryViewElements.cs" />
<Compile Include="Components\Views\QueryViews.cs" />
<Compile Include="Components\Views\SectionBox.cs" />
Expand Down

0 comments on commit 2905072

Please sign in to comment.