using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Windows;
using CommunityToolkit.Mvvm.Input;
using Nice3point.Revit.Toolkit.External.Handlers;
using ShrlAlgo.RvKits.RvCommon;
using System.ComponentModel;
using System.Windows.Controls;
namespace ShrlAlgo.RvKits.UIRibbon;
public class ModifyTabApp
{
public ModifyTabApp(UIApplication uiapp)
{
handler = new ActionEventHandler();
this.uiapp = uiapp;
var tab = ComponentManager.Ribbon.Tabs.FirstOrDefault(ribbonTab => ribbonTab.Id == "Modify");
SelectionPanel(tab);
//FilterPanel(tab);
AlignPanel(tab);
}
private readonly ActionEventHandler handler;
private readonly UIApplication uiapp;
private Document Document => UIDocument.Document;
private UIDocument UIDocument => uiapp.ActiveUIDocument;
///
/// 对齐元素
///
/// 需对齐的元素集合
/// 对齐的类型
private static void AlignByType(List alignElements, AlignType alignType)
{
switch (alignType)
{
case AlignType.Left:
{
//最左的元素
var leftAlignElement = alignElements.OrderBy(x => x.UpLeft.X).FirstOrDefault();
foreach (var alignElement in alignElements)
{
XYZ resultingPoint = new(leftAlignElement.UpLeft.X, alignElement.UpLeft.Y, 0);
alignElement.MoveTo(resultingPoint, AlignType.Left);
}
break;
}
case AlignType.Right:
{
var rightAlignElement = alignElements.OrderByDescending(x => x.UpRight.X).FirstOrDefault();
foreach (var alignElement in alignElements)
{
XYZ resultingPoint = new(rightAlignElement.UpRight.X, alignElement.UpRight.Y, 0);
alignElement.MoveTo(resultingPoint, AlignType.Right);
}
break;
}
case AlignType.Up:
{
var upAlignElement = alignElements.OrderByDescending(x => x.UpRight.Y).FirstOrDefault();
foreach (var alignElement in alignElements)
{
XYZ resultingPoint = new(alignElement.UpRight.X, upAlignElement.UpRight.Y, 0);
alignElement.MoveTo(resultingPoint, AlignType.Up);
}
break;
}
case AlignType.Down:
{
var farthestAlign = alignElements.OrderBy(x => x.DownRight.Y).FirstOrDefault();
foreach (var alignElement in alignElements)
{
XYZ resultingPoint = new(alignElement.DownRight.X, farthestAlign.DownRight.Y, 0);
alignElement.MoveTo(resultingPoint, AlignType.Down);
}
break;
}
case AlignType.HorizontallyCenter: //同一条垂直轴
{
var sortedElements = alignElements.OrderBy(x => x.UpRight.X).ToList();
var rightElement = sortedElements.LastOrDefault();
var leftElement = sortedElements.FirstOrDefault();
var xCoord = (rightElement.Center.X + leftElement.Center.X) / 2;
foreach (var alignElement in sortedElements)
{
XYZ resultingPoint = new(xCoord, alignElement.Center.Y, 0);
alignElement.MoveTo(resultingPoint, AlignType.HorizontallyCenter);
}
break;
}
case AlignType.VerticallyCenter: //同一条水平轴
{
var sortedElements = alignElements.OrderBy(x => x.UpRight.Y).ToList();
var upperAlignAnnotation = sortedElements.LastOrDefault();
var lowerAlignAnnotation = sortedElements.FirstOrDefault();
var yCoord = (upperAlignAnnotation.Center.Y + lowerAlignAnnotation.Center.Y) / 2;
foreach (var alignElement in sortedElements)
{
XYZ resultingPoint = new(alignElement.Center.X, yCoord, 0);
alignElement.MoveTo(resultingPoint, AlignType.VerticallyCenter);
}
break;
}
case AlignType.Bottom:
{
var sortedElements = alignElements.OrderBy(z => z.Bottom).ToList();
var elevation = sortedElements.FirstOrDefault();
foreach (var alignElement in sortedElements)
{
XYZ resultingPoint = new(0, 0, elevation.Bottom);
alignElement.MoveTo(resultingPoint, AlignType.Bottom);
}
break;
}
case AlignType.Middle:
{
var sortedElements = alignElements.OrderBy(z => z.Middle).ToList();
//var middle = sortedElements.FirstOrDefault();
var topAlign = sortedElements.LastOrDefault();
var botAlign = sortedElements.FirstOrDefault();
var middle = (topAlign.Middle + botAlign.Middle) / 2;
foreach (var alignElement in sortedElements)
{
XYZ resultingPoint = new(0, 0, middle);
alignElement.MoveTo(resultingPoint, AlignType.Middle);
}
break;
}
case AlignType.Top:
{
var sortedElements = alignElements.OrderByDescending(z => z.Top).ToList();
var top = sortedElements.FirstOrDefault();
foreach (var alignElement in sortedElements)
{
XYZ resultingPoint = new(0, 0, top.Top);
alignElement.MoveTo(resultingPoint, AlignType.Top);
}
break;
}
}
}
///
/// 对齐命令
///
///
private void AlignCommand(object obj)
{
if (obj is not Autodesk.Windows.RibbonButton rb)
{
return;
}
var alignType = (AlignType)rb.CommandParameter;
handler.Raise(_ =>
{
Document.Invoke(
_ =>
{
var selectedIds = UIDocument.Selection.GetElementIds();
var alignElements = (from id in selectedIds
let e = new AlignModelElement(Document.GetElement(id))
select e).ToList();
//List alignElements = new();
//foreach (var id in selectedIds)
//{
// var e = Document.GetElement(id);
// alignElements.Add(new AlignModelElement(e));
//}
AlignByType(alignElements, alignType);
},
alignType.GetAttribute().Description);
});
}
///
/// 是否能进行对齐操作
///
///
private bool CanAlign()
{
return UIDocument?.Selection
.GetElementIds()
.Count(id => Document.GetElement(id) is GenericForm || Document.GetElement(id).Category?.CategoryType == CategoryType.Model) > 1;
}
///
/// 对齐面板
///
///
private void AlignPanel(RibbonTab tab)
{
//新建面板
Autodesk.Windows.RibbonPanel alignElemsPanel = new() { FloatingOrientation = System.Windows.Controls.Orientation.Vertical };
//面板资源
RibbonPanelSource alignSource = new() { Id = "ID_Layout_Panel", Title = "布局" };
alignElemsPanel.Source = alignSource;
//面板按钮
var alignLeftBtn = new Autodesk.Windows.RibbonButton
{
Image = Properties.Resources.align_left_16px.ToBitmapSource(),
//LargeImage = Properties.Resources.align_left_16px.ToBitmapSource(),
Size = RibbonItemSize.Standard,
ShowText = true,
Id = "ID_ALL_BTN",
Name = "左对齐",
ToolTip = "根据几何元素范围,元素左侧对齐",
Text = "左对齐",
IsCheckable = true,
CommandHandler = new RelayCommand