bool ICommandHandler.OnCommand(string MenuId) { switch (MenuId) { case "MenuId.Length.ModifyWithMouse": ModifyWithMouse?.Invoke(this, false); return(true); case "MenuId.Length.DistanceOfCurve": Frame.SetAction(new CADability.Actions.ConstructDistanceOfCurve(this)); return(true); case "MenuId.Length.DistanceTwoPoints": Frame.SetAction(new CADability.Actions.ConstructDistanceTwoPoints(this)); return(true); case "MenuId.Length.DistancePointCurve": Frame.SetAction(new CADability.Actions.ConstructDistancePointCurve(this)); return(true); case "MenuId.Length.DistanceTwoCurves": Frame.SetAction(new CADability.Actions.ConstructDistanceTwoCurves(this)); return(true); case "MenuId.Length.DoubleValue": this.SetLength(this.GetLength() * 2.0); return(true); case "MenuId.Length.HalfValue": this.SetLength(this.GetLength() * 0.5); return(true); case "MenuId.Length.NameVariable": Frame.Project.SetNamedValue(null, GetLength()); return(true); case "MenuId.Length.FormatSettings": { Frame.ShowPropertyDisplay("Global"); IPropertyPage pd = Frame.GetPropertyDisplay("Global"); IPropertyEntry sp = pd.FindFromHelpLink("Setting.Formatting"); if (sp != null) { pd.OpenSubEntries(sp, true); sp = pd.FindFromHelpLink("Setting.Formatting.GeneralDouble"); if (sp != null) { pd.OpenSubEntries(sp, true); pd.SelectEntry(sp); } } } return(true); // return false; } return(false); }
bool ICommandHandler.OnCommand(string MenuId) { switch (MenuId) { case "MenuId.Vector.ModifyWithMouse": if (ModifyWithMouse != null) { ModifyWithMouse(this, false); } return(true); case "MenuId.Vector.DirectionOfCurve": Frame.SetAction(new CADability.Actions.ConstructDirectionOfCurve(this)); return(true); case "MenuId.Vector.DirectionOfSurface": Frame.SetAction(new CADability.Actions.ConstructDirectionOfSurface(this)); return(true); case "MenuId.Vector.DirectionTwoPoints": Frame.SetAction(new CADability.Actions.ConstructDirectionTwoPoints(this)); return(true); case "MenuId.Vector.NameVariable": Frame.Project.SetNamedValue(null, GetGeoVector()); return(true); // return false; case "MenuId.Vector.FormatSettings": { Frame.ShowPropertyDisplay("Global"); IPropertyPage pd = Frame.GetPropertyDisplay("Global"); IPropertyEntry sp = pd.FindFromHelpLink("Setting.Formatting"); if (sp != null) { pd.OpenSubEntries(sp, true); sp = pd.FindFromHelpLink("Setting.Formatting.Vector"); if (sp != null) { pd.OpenSubEntries(sp, true); pd.SelectEntry(sp); } } } return(true); } return(false); }
bool ICommandHandler.OnCommand(string MenuId) { if (FilterCommandEvent != null) { bool handled = false; FilterCommandEvent(this, MenuId, null, ref handled); if (handled) { return(true); } } // maybe this property is a subproperty (e.g. Multipoint) then use the parent commandhandler first ICommandHandler ch = propertyPage.GetParent(this) as ICommandHandler; if (ch != null) { if (ch.OnCommand(MenuId)) { return(true); } } switch (MenuId) { case "MenuId.Point.ModifyWithMouse": if (ModifyWithMouse != null) { ModifyWithMouse(this, false); } else if (autoModifyWithMouse) { generalGeoPointAction = new GeneralGeoPointAction(this); Frame.SetAction(generalGeoPointAction); } return(true); case "MenuId.Point.IntermediatePoint": Frame.SetAction(new ConstructMidPoint(this)); return(true); case "MenuId.Point.ObjectPoint": Frame.SetAction(new ConstructObjectPoint(this)); return(true); case "MenuId.Point.IntersectionTwoCurves": Frame.SetAction(new ConstructIntersectPoint(this)); return(true); case "MenuId.Point.OffsetByVector": Frame.SetAction(new ConstructVectorPoint(this)); return(true); case "MenuId.Point.Polar": Frame.SetAction(new ConstructPolarPoint(this)); return(true); case "MenuId.Point.NameVariable": Frame.Project.SetNamedValue(null, GetGeoPoint()); return(true); case "MenuId.Point.FormatSettings": { Frame.ShowPropertyDisplay("Global"); IPropertyPage pd = Frame.GetPropertyDisplay("Global"); IPropertyEntry sp = pd.FindFromHelpLink("Setting.Formatting"); if (sp != null) { pd.OpenSubEntries(sp, true); sp = pd.FindFromHelpLink("Setting.Formatting.Coordinate"); if (sp != null) { pd.OpenSubEntries(sp, true); pd.SelectEntry(sp); } } } return(true); default: return(false); } }
private void ShowContextMenu(Point mousePoint, IView vw) { currentView = vw; GeoObjectList result = new GeoObjectList(); int pickRadius = soa.Frame.GetIntSetting("Select.PickRadius", 5); Projection.PickArea pa = vw.Projection.GetPickSpace(new Rectangle(mousePoint.X - pickRadius, mousePoint.Y - pickRadius, pickRadius * 2, pickRadius * 2)); IActionInputView pm = vw as IActionInputView; GeoObjectList fl = vw.Model.GetObjectsFromRect(pa, new Set <Layer>(pm.GetVisibleLayers()), PickMode.onlyFaces, null); // returns all the face under the cursor // in most cases there is only a single face, which is of interest, only when we have two solids with same or overlapping faces // and one of them is not selectable without also selecting the other, we want both. faces = new List <Face>(); shells = new List <Shell>(); // only Shells, which are not part of a Solid solids = new List <Solid>(); features = new List <IEnumerable <Face> >(); double delta = vw.Model.Extent.Size * 1e-4; double mindist = double.MaxValue; for (int i = 0; i < fl.Count; i++) { if (fl[i] is Face face) // this should always be the case { double z = face.Position(pa.FrontCenter, pa.Direction, 0); if (z < mindist) { if (z < mindist - delta) { faces.Clear(); } faces.Add(face); mindist = z; } } } HashSet <Edge> relevantEdges = new HashSet <Edge>(); for (int i = 0; i < faces.Count; i++) { relevantEdges.UnionWith(faces[i].AllEdges); if (faces[i].Owner is Shell shell) { if (shell.Owner is Solid sld) { if (!solids.Contains(sld)) { solids.Add(sld); } } else { if (!shells.Contains(shell)) { shells.Add(shell); } } } } for (int i = 0; i < faces.Count; i++) { if (faces[i].Owner is Shell shell) { for (int j = 0; j < faces[i].OutlineEdges.Length; j++) { Edge edg = faces[i].OutlineEdges[j]; if (edg.IsPartOfHole(edg.OtherFace(faces[i]))) { Face otherFace = edg.OtherFace(faces[i]); if (otherFace != null) { Edge[] hole = otherFace.GetHole(edg); List <Edge[]> loops = new List <Edge[]> { hole }; List <IEnumerable <Face> > lfeatures = new List <IEnumerable <Face> >(); List <IEnumerable <Face> > lids = new List <IEnumerable <Face> >(); HashSet <Face> startWith = new HashSet <Face>(); foreach (Edge edge in hole) { startWith.Add(edge.OtherFace(otherFace)); // all faces that are connected to the hole in "otherFace" } shell.FeaturesFromEdges(loops, lfeatures, lids, startWith); for (int k = 0; k < lfeatures.Count; k++) { if (lfeatures[k].Count() < shell.Faces.Length * 0.5) { features.Add(lfeatures[k]); } } } } } } } curves = vw.Model.GetObjectsFromRect(pa, new Set <Layer>(pm.GetVisibleLayers()), PickMode.onlyEdges, null); // returns edges and curves edges = new List <Edge>(); // we only accept edges, which belong to one of the selected faces for (int i = curves.Count - 1; i >= 0; --i) { if (curves[i].Owner is Edge edge) { if (relevantEdges.Contains(edge)) { edges.Add(edge); } else { double z = curves[i].Position(pa.FrontCenter, pa.Direction, 0); if (z - delta < mindist) { edges.Add(edge); // this is an edge in front of the closest face } } curves.Remove(i); } else { double z = curves[i].Position(pa.FrontCenter, pa.Direction, 0); if (z - delta > mindist) { curves.Remove(i); } } } // now we have curves, edges, faces, shells and solids (text, hatch, block, dimension not yet implemented) from the right click // we also need access to the already selected edges and faces to GeoObjectList selobj = soa.GetSelectedObjects(); HashSet <Edge> selectedEdges = new HashSet <Edge>(); HashSet <Face> selectedFaces = new HashSet <Face>(); foreach (IGeoObject go in selobj) { if (go is ICurve && go.Owner is Edge edg) { selectedEdges.Add(edg); } if (go is Face fc) { selectedFaces.Add(fc); } } List <MenuWithHandler> cm = new List <MenuWithHandler>(); Shell owningShell = null; if (edges.Count > 0) { owningShell = (edges[0].Owner as Face).Owner as Shell; } if (owningShell == null && faces.Count > 0) { owningShell = (faces[0].Owner as Shell); } if (owningShell == null && selectedFaces.Count > 0) { owningShell = selectedFaces.First().Owner as Shell; } if (owningShell == null && selectedEdges.Count > 0) { owningShell = (selectedEdges.First().Owner as Face).Owner as Shell; } if (owningShell != null) { for (int i = 0; i < features.Count; i++) { List <Face> featureI = new List <Face>(features[i]); MenuWithHandler mh = new MenuWithHandler("MenuId.Feature"); mh.OnSelected = (m, selected) => { currentMenuSelection.Clear(); currentMenuSelection.AddRange(featureI.ToArray()); currentView.Invalidate(PaintBuffer.DrawingAspect.Select, currentView.DisplayRectangle); }; MenuWithHandler positionFeature = new MenuWithHandler("MenuId.Feature.Position"); MenuWithHandler nameFeature = new MenuWithHandler("MenuId.Feature.Name"); mh.SubMenus = new MenuWithHandler[] { positionFeature, nameFeature }; // this is very rudimentary. We have to provide a version of ParametricsDistanceAction, where you can select from and to object. Only axis is implemented Shell shell = featureI[0].Owner as Shell; GeoObjectList fa = shell.FeatureAxis; Line axis = null; foreach (IGeoObject geoObject in fa) { Face axisOf = geoObject.UserData.GetData("CADability.AxisOf") as Face; if (axisOf != null) { if (featureI.Contains(axisOf)) { axis = geoObject as Line; } } if (axis != null) { break; } } positionFeature.OnCommand = (menuId) => { ParametricsDistanceActionOld pd = new ParametricsDistanceActionOld(featureI, soa.Frame); soa.Frame.SetAction(pd); return(true); }; positionFeature.OnSelected = (menuId, selected) => { currentMenuSelection.Clear(); currentMenuSelection.AddRange(featureI.ToArray()); currentView.Invalidate(PaintBuffer.DrawingAspect.Select, currentView.DisplayRectangle); }; nameFeature.OnCommand = (menuId) => { string name = shell.GetNewFeatureName(); shell.AddFeature(name, featureI); if (shell.Owner is Solid sld) { soa.SetSelectedObject(sld); IPropertyEntry toEdit = soa.Frame.ControlCenter.FindItem(name); if (toEdit != null) { List <IPropertyEntry> parents = new List <IPropertyEntry>(); if (toEdit != null) { IPropertyEntry p = toEdit; while ((p = p.Parent as IPropertyEntry) != null) { parents.Add(p); } IPropertyPage propertyPage = parents[parents.Count - 1].Parent as IPropertyPage; if (propertyPage != null) { for (int k = parents.Count - 1; k >= 0; --k) { propertyPage.OpenSubEntries(parents[k], true); } toEdit.StartEdit(false); } } } } return(true); }; nameFeature.OnSelected = (menuId, selected) => { currentMenuSelection.Clear(); currentMenuSelection.AddRange(featureI.ToArray()); currentView.Invalidate(PaintBuffer.DrawingAspect.Select, currentView.DisplayRectangle); }; cm.Add(mh); } } for (int i = 0; i < curves.Count; i++) { // No implementation for simple curves yet. // We would need a logical connection structure as in vertex->edge->face->shell in 2d curves, which we currently do not have. Face faceWithAxis = (curves[i] as IGeoObject).UserData.GetData("CADability.AxisOf") as Face; if (faceWithAxis != null) { MenuWithHandler mh = new MenuWithHandler("MenuId.Axis"); mh.SubMenus = GetFacesSubmenus(faceWithAxis).ToArray(); mh.Target = this; IGeoObject curveI = curves[i] as IGeoObject; mh.OnSelected = (m, selected) => { currentMenuSelection.Clear(); currentMenuSelection.Add(curveI); currentView.Invalidate(PaintBuffer.DrawingAspect.Select, currentView.DisplayRectangle); }; cm.Add(mh); } } for (int i = 0; i < edges.Count; i++) { MenuWithHandler mh = new MenuWithHandler(); mh.ID = "MenuId.Edge." + i.ToString(); mh.Text = StringTable.GetString("MenuId.Edge", StringTable.Category.label); List <MenuWithHandler> lmh = new List <MenuWithHandler>(); MenuWithHandler selectMoreEdges = new MenuWithHandler("MenuId.SelectMoreEdges"); lmh.Add(selectMoreEdges); Edge edgeI = edges[i]; selectMoreEdges.OnCommand = (menuId) => { soa.SetSelectedObject(edgeI.Curve3D as IGeoObject); soa.OverwriteMode(PickMode.onlyEdges); return(true); }; lmh.AddRange(edges[i].GetContextMenu(soa.Frame)); mh.SubMenus = lmh.ToArray(); mh.Target = this; cm.Add(mh); } for (int i = 0; i < faces.Count; i++) { MenuWithHandler mh = new MenuWithHandler(); mh.ID = "MenuId.Face." + i.ToString(); mh.Text = StringTable.GetString("MenuId.Face", StringTable.Category.label); List <MenuWithHandler> lmh = new List <MenuWithHandler>(); MenuWithHandler selectMoreFaces = new MenuWithHandler("MenuId.SelectMoreFaces"); lmh.Add(selectMoreFaces); Face faceI = faces[i]; selectMoreFaces.OnCommand = (menuId) => { soa.SetSelectedObject(faceI); soa.OverwriteMode(PickMode.onlyFaces); return(true); }; lmh.AddRange(GetFacesSubmenus(faces[i])); if (owningShell != null) { double thickness = owningShell.GetGauge(faces[i], out HashSet <Face> frontSide, out HashSet <Face> backSide); if (thickness != double.MaxValue && frontSide.Count > 0) { MenuWithHandler gauge = new MenuWithHandler("MenuId.Gauge"); gauge.OnCommand = (menuId) => { ParametricsOffset po = new ParametricsOffset(frontSide, backSide, soa.Frame, thickness); soa.Frame.SetAction(po); return(true); }; gauge.OnSelected = (menuId, selected) => { currentMenuSelection.Clear(); currentMenuSelection.AddRange(frontSide.ToArray()); currentMenuSelection.AddRange(backSide.ToArray()); currentView.Invalidate(PaintBuffer.DrawingAspect.Select, currentView.DisplayRectangle); }; lmh.Add(gauge); } int n = owningShell.GetFaceDistances(faces[i], out List <Face> distanceTo, out List <double> distance, out List <GeoPoint> pointsFrom, out List <GeoPoint> pointsTo); for (int j = 0; j < n; j++) { if (backSide == null || !backSide.Contains(distanceTo[j])) // this is not already used as gauge { HashSet <Face> capturedFaceI = new HashSet <Face>(new Face[] { faces[i] }); HashSet <Face> capturedDistTo = new HashSet <Face>(new Face[] { distanceTo[j] }); double capturedDistance = distance[j]; GeoPoint capturedPoint1 = pointsFrom[j]; GeoPoint capturedPoint2 = pointsTo[j]; GeoObjectList feedbackArrow = currentView.Projection.MakeArrow(pointsFrom[j], pointsTo[j], currentView.Projection.ProjectionPlane, Projection.ArrowMode.circleArrow); MenuWithHandler faceDist = new MenuWithHandler("MenuId.FaceDistance"); faceDist.OnCommand = (menuId) => { ParametricsDistanceAction pd = new ParametricsDistanceAction(capturedFaceI, capturedDistTo, capturedPoint1, capturedPoint2, soa.Frame); soa.Frame.SetAction(pd); return(true); }; faceDist.OnSelected = (menuId, selected) => { currentMenuSelection.Clear(); currentMenuSelection.AddRange(capturedFaceI.ToArray()); currentMenuSelection.AddRange(capturedDistTo.ToArray()); currentMenuSelection.AddRange(feedbackArrow); currentView.Invalidate(PaintBuffer.DrawingAspect.Select, currentView.DisplayRectangle); }; lmh.Add(faceDist); } } } mh.SubMenus = lmh.ToArray(); mh.Target = this; cm.Add(mh); //cm.AddRange(GetFacesSubmenus(faces)); } for (int i = 0; i < faces.Count; i++) { if (faces[i].Owner is Shell shell) { Shell sh = shell.FeatureFromFace(faces[i]); } } for (int i = 0; i < edges.Count; i++) { if (edges[i].PrimaryFace.Owner is Shell shell) { //shell.FeatureFromEdges(edges[i].PrimaryFace); } } for (int i = 0; i < shells.Count; i++) { MenuWithHandler mh = new MenuWithHandler(); mh.ID = "MenuId.Shell." + i.ToString(); mh.Text = StringTable.GetString("MenuId.Shell", StringTable.Category.label); mh.SubMenus = shells[i].GetContextMenu(soa.Frame); mh.Target = this; cm.Add(mh); } for (int i = 0; i < solids.Count; i++) { MenuWithHandler mh = new MenuWithHandler(); mh.ID = "MenuId.Solid." + i.ToString(); mh.Text = StringTable.GetString("MenuId.Solid", StringTable.Category.label); mh.SubMenus = solids[i].GetContextMenu(soa.Frame); mh.Target = this; cm.Add(mh); } { // selection independent menu items MenuWithHandler mh = new MenuWithHandler(); mh.ID = "MenuId.Show"; mh.Text = StringTable.GetString("MenuId.Show", StringTable.Category.label); MenuWithHandler mhShowHidden = new MenuWithHandler(); mhShowHidden.ID = "MenuId.ShowHidden"; mhShowHidden.Text = StringTable.GetString("MenuId.ShowHidden", StringTable.Category.label); mhShowHidden.OnCommand = (menuId) => { foreach (IGeoObject geoObject in vw.Model) { if (geoObject.Layer != null && geoObject.Layer.Name == "CADability.Hidden") { Layer layer = geoObject.UserData.GetData("CADability.OriginalLayer") as Layer; if (layer != null) { geoObject.Layer = layer; } } } return(true); }; MenuWithHandler mhShowAxis = new MenuWithHandler(); mhShowAxis.ID = "MenuId.ShowAxis"; mhShowAxis.Text = StringTable.GetString("MenuId.ShowAxis", StringTable.Category.label); mhShowAxis.OnCommand = (menuId) => { bool isOn = false; foreach (IGeoObject geoObject in vw.Model) { Shell shell = null; if (geoObject is Solid solid) { shell = solid.Shells[0]; } else if (geoObject is Shell sh) { shell = sh; } if (shell != null && shell.FeatureAxis.Count > 0) { isOn = shell.FeatureAxis[0].IsVisible; break; } } using (vw.Canvas.Frame.Project.Undo.UndoFrame) { foreach (IGeoObject geoObject in vw.Model) { if (geoObject is Solid solid) { solid.ShowFeatureAxis = !isOn; } else if (geoObject is Shell shell) { shell.ShowFeatureAxis = !isOn; } } } return(true); }; mhShowAxis.OnUpdateCommand = (menuId, commandState) => { bool isOn = false; foreach (IGeoObject geoObject in vw.Model) { Shell shell = null; if (geoObject is Solid solid) { shell = solid.Shells[0]; } else if (geoObject is Shell sh) { shell = sh; } if (shell != null && shell.FeatureAxis.Count > 0) { isOn = shell.FeatureAxis[0].IsVisible; break; } } commandState.Checked = isOn; return(true); }; mh.SubMenus = new MenuWithHandler[] { mhShowHidden, mhShowAxis }; mh.Target = this; cm.Add(mh); } vw.SetPaintHandler(PaintBuffer.DrawingAspect.Select, new PaintView(OnRepaintSelect)); mousePoint.X += vw.DisplayRectangle.Width / 8; // find a better place for the menu position, using the extent of the objects vw.Canvas.ShowContextMenu(cm.ToArray(), mousePoint, ContextMenuCollapsed); }