/// <summary> /// Update our reading to reflect the current selection /// </summary> protected override void OnORMSelectionContainerChanged() { if (CurrentORMSelectionContainer != null) { ICollection selectedObjects = base.GetSelectedComponents(); FactType theFact = null; FactType secondaryFact = null; if (selectedObjects != null) { foreach (object element in selectedObjects) { FactType testFact = ORMEditorUtility.ResolveContextFactType(element); // Handle selection of multiple elements as long as // they all resolve to the same fact if (theFact == null) { theFact = testFact; Role testImpliedRole; RoleProxy proxy; ObjectifiedUnaryRole objectifiedUnaryRole; if (null != (testImpliedRole = element as Role)) { if (null != (proxy = testImpliedRole.Proxy)) { secondaryFact = proxy.FactType; } else if (null != (objectifiedUnaryRole = testImpliedRole.ObjectifiedUnaryRole)) { secondaryFact = objectifiedUnaryRole.FactType; } } } else if (testFact != theFact) { theFact = null; break; } else { secondaryFact = null; } } } if (theFact != null && theFact.HasImplicitReadings) { theFact = null; secondaryFact = null; } ActiveFactType activeFact = EditingFactType; FactType currentFact = activeFact.FactType; FactType currentImpliedFact = activeFact.ImpliedFactType; if (theFact == null && currentFact != null) { EditingFactType = ActiveFactType.Empty; } //selection could change between the shapes that are related to the fact else if (theFact != currentFact || secondaryFact != currentImpliedFact) { ReadOnlyCollection <RoleBase> displayOrder = null; IORMDesignerView designerView; DiagramView designer; if (null != (designerView = CurrentORMSelectionContainer as IORMDesignerView) && null != (designer = designerView.CurrentDesigner)) { SelectedShapesCollection shapes = designer.DiagramClientView.Selection; if (shapes.Count == 1) { DiagramItem item = null; foreach (DiagramItem iter in shapes) { item = iter; break; } ShapeElement shape = item.Shape; FactTypeShape factShape = shape as FactTypeShape; while (factShape == null) { shape = shape.ParentShape; if (shape == null) { break; } factShape = shape as FactTypeShape; } if (factShape != null) { FactType shapeFactType = factShape.AssociatedFactType; Objectification objectification; if (shapeFactType == theFact) { displayOrder = new ReadOnlyCollection <RoleBase>(factShape.DisplayedRoleOrder); } else if (secondaryFact == null && null != (objectification = shapeFactType.ImpliedByObjectification) && objectification.NestedFactType == theFact) { secondaryFact = shapeFactType; } } } } EditingFactType = new ActiveFactType(theFact, secondaryFact, displayOrder); } } else { EditingFactType = ActiveFactType.Empty; } }
/// <summary> /// Show selected properties from the <see cref="FactType.NestingType"/> and the /// <see cref="Objectification.NestedFactType"/> for an objectified <see cref="FactType"/>, /// as well as expandable nodes for each of the underlying instances. /// </summary> public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { FactType factType = ModelElement; if (FactTypeShape.ShouldDrawObjectification(factType)) { FactTypeShape factTypeShape = PresentationElement; Objectification objectification = factType.Objectification; ObjectType nestingType = objectification.NestingType; bool nestingTypeHasRelatedTypes = nestingType.IsSubtypeOrSupertype; DomainDataDirectory domainDataDirectory = factType.Store.DomainDataDirectory; EnsureDomainAttributesInitialized(domainDataDirectory); PropertyDescriptorCollection retVal; if (factTypeShape.DisplayAsObjectType) { retVal = new PropertyDescriptorCollection(null); Type componentType = typeof(FactTypeShape); foreach (PropertyDescriptor nestingTypeDescriptor in TypeDescriptor.GetProperties(nestingType)) { if (nestingTypeDescriptor.Name == "NestedFactType") { continue; } retVal.Add(EditorUtility.RedirectPropertyDescriptor(nestingType, nestingTypeDescriptor, componentType)); } retVal.Add(CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayAsObjectTypeDomainPropertyId), DisplayAsObjectTypeDomainPropertyAttributes)); retVal.Add(CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.ExpandRefModeDomainPropertyId), ExpandRefModeDomainPropertyAttributes)); retVal.Add(new ObjectifyingEntityTypePropertyDescriptor(factType, domainDataDirectory.FindDomainRole(Objectification.NestingTypeDomainRoleId), NestedFactTypeDomainRoleAttributes)); retVal.Add(new ObjectifiedFactTypePropertyDescriptor(nestingType, domainDataDirectory.FindDomainRole(Objectification.NestedFactTypeDomainRoleId), NestingTypeDomainRoleAttributes)); if (nestingTypeHasRelatedTypes) { retVal.Add(CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayRelatedTypesDomainPropertyId), DisplayRelatedTypesDomainPropertyAttributes)); } } else { PropertyDescriptor[] descriptors = new PropertyDescriptor[nestingTypeHasRelatedTypes ? 9 : 8]; descriptors[0] = CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.ConstraintDisplayPositionDomainPropertyId), ConstraintDisplayPositionDomainPropertyAttributes); descriptors[1] = CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayOrientationDomainPropertyId), DisplayOrientationDomainPropertyAttributes); descriptors[2] = CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayRoleNamesDomainPropertyId), DisplayRoleNamesDomainPropertyAttributes); descriptors[3] = CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayAsObjectTypeDomainPropertyId), DisplayAsObjectTypeDomainPropertyAttributes); descriptors[4] = CreatePropertyDescriptor(nestingType, domainDataDirectory.FindDomainProperty(ORMNamedElement.NameDomainPropertyId), NameDomainPropertyAttributes); descriptors[5] = CreatePropertyDescriptor(nestingType, domainDataDirectory.FindDomainProperty(ObjectType.IsIndependentDomainPropertyId), IsIndependentDomainPropertyAttributes); descriptors[6] = new ObjectifyingEntityTypePropertyDescriptor(factType, domainDataDirectory.FindDomainRole(Objectification.NestingTypeDomainRoleId), NestedFactTypeDomainRoleAttributes); descriptors[7] = new ObjectifiedFactTypePropertyDescriptor(nestingType, domainDataDirectory.FindDomainRole(Objectification.NestedFactTypeDomainRoleId), NestingTypeDomainRoleAttributes); if (nestingTypeHasRelatedTypes) { descriptors[8] = CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayRelatedTypesDomainPropertyId), DisplayRelatedTypesDomainPropertyAttributes); } retVal = new PropertyDescriptorCollection(descriptors); } // This mockup of important properties means that extension providers cannot add properties // here by adding to the objecttype or facttype. Use an extension on the Objectification type // itself to add extension properties. ((IFrameworkServices)factType.Store).PropertyProviderService.GetProvidedProperties(objectification, retVal); return(retVal); } return(base.GetProperties(attributes)); }
public static DslModeling::LinkedElementCollection<global::ORMSolutions.ORMArchitect.Core.ObjectModel.RoleBase> GetRoleDisplayOrderCollection(FactTypeShape element) { return new DslModeling::LinkedElementCollection<global::ORMSolutions.ORMArchitect.Core.ObjectModel.RoleBase>(element, FactTypeShapeDomainRoleId); }
/// <summary> /// Constructor /// Creates a FactTypeShapeHasRoleDisplayOrder link in the same Partition as the given FactTypeShape /// </summary> /// <param name="source">FactTypeShape to use as the source of the relationship.</param> /// <param name="target">RoleBase to use as the target of the relationship.</param> public FactTypeShapeHasRoleDisplayOrder(FactTypeShape source, global::ORMSolutions.ORMArchitect.Core.ObjectModel.RoleBase target) : base((source != null ? source.Partition : null), new DslModeling::RoleAssignment[]{new DslModeling::RoleAssignment(FactTypeShapeHasRoleDisplayOrder.FactTypeShapeDomainRoleId, source), new DslModeling::RoleAssignment(FactTypeShapeHasRoleDisplayOrder.RoleDisplayOrderDomainRoleId, target)}, null) { }
/// <summary> /// Central function to return member variables to a clean state. /// Called by the constructor and the deactivation sequence. /// </summary> private void Reset() { myAddedConstraint = null; myDropTargetShape = null; }
/// <summary> /// An IMS event to track the shape element added to the associated /// diagram during this connect action. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void InternalConstraintAddedEvent(object sender, ElementAddedEventArgs e) { if (myAddedConstraint == null) { UniquenessConstraint candidate = e.ModelElement as UniquenessConstraint; if (candidate != null && candidate.IsInternal) { ORMDiagram d = Diagram as ORMDiagram; if (d != null) { // Find the shape associated with the fact type we added to LinkedElementCollection<FactType> candidateFacts = candidate.FactTypeCollection; if (candidateFacts.Count != 0) { FactTypeShape shape = d.FindShapeForElement(candidateFacts[0]) as FactTypeShape; if (shape != null) { myDropTargetShape = shape; myAddedConstraint = candidate; } } } } } }
/// <summary> /// Set this mouse action as the active action on the /// diagram of the given shape. /// </summary> /// <param name="attachToShape">The shape the constraint is being attached to.</param> /// <param name="constraint">The constraint being connected.</param> /// <param name="clientView">The active DiagramClientView</param> public void ChainMouseAction(FactTypeShape attachToShape, UniquenessConstraint constraint, DiagramClientView clientView) { DiagramView activeView = Diagram.ActiveDiagramView; if (activeView != null) { // Move on to the selection action clientView.ActiveMouseAction = this; // Now emulate a mouse click in the middle of the added constraint. The click // actions provide a starting point for the connect action, so a mouse move // provides a drag line. Point emulateClickPoint = clientView.WorldToDevice(attachToShape.GetAbsoluteConstraintAttachPoint(constraint)); DiagramMouseEventArgs mouseEventArgs = new DiagramMouseEventArgs(new MouseEventArgs(MouseButtons.Left, 1, emulateClickPoint.X, emulateClickPoint.Y, 0), clientView); MouseDown(mouseEventArgs); Click(new DiagramPointEventArgs(emulateClickPoint.X, emulateClickPoint.Y, PointRelativeTo.Client, clientView)); MouseUp(mouseEventArgs); attachToShape.Invalidate(true); // An extra move lets us chain when the mouse is not on the design surface, // such as when we are being activated via the task list. MouseMove(mouseEventArgs); ORMDiagram.SelectToolboxItem(activeView, ResourceStrings.ToolboxInternalUniquenessConstraintItemId); FactTypeShape.ActiveInternalUniquenessConstraintConnectAction = this; } }
private void Reset() { mySelectedRoles = null; mySourceShape = null; myIUC = null; myLastMouseMoveItem = null; myPendingOnClickedAction = OnClickedAction.Normal; FactTypeShape.ActiveInternalUniquenessConstraintConnectAction = null; }
/// <summary> /// Add a source shape or commit/cancel the action by forwarding the /// click to the base class, or modify the current role sequence by handling /// the click locally. /// </summary> /// <param name="e">MouseActionEventArgs</param> protected override void OnClicked(MouseActionEventArgs e) { switch (myPendingOnClickedAction) { case OnClickedAction.Commit: myPendingOnClickedAction = OnClickedAction.Normal; // Letting the click through to the base ConnectAction // at this point (a constraint is selected and a role has been // double-clicked) will force the connect action to finish. base.OnClicked(e); return; case OnClickedAction.CheckForCommit: myPendingOnClickedAction = OnClickedAction.Normal; break; } DiagramMouseEventArgs args = CurrentDiagramArgs as DiagramMouseEventArgs; if (args != null) { DiagramItem item = args.DiagramHitTestInfo.HitDiagramItem; ModelElement currentElement = null; foreach (ModelElement elem in item.RepresentedElements) { currentElement = elem; break; } UniquenessConstraint internalUniquenessConstraint; RoleBase roleBase; if (null != (internalUniquenessConstraint = currentElement as UniquenessConstraint) && internalUniquenessConstraint.IsInternal) { if (mySourceShape == null) { // Let the click through to the base to officially begin the drag action base.OnClicked(e); mySourceShape = item.Shape as FactTypeShape; myIUC = internalUniquenessConstraint; } } else if (mySourceShape != null) { if (null != (roleBase = currentElement as RoleBase)) { Role role = roleBase.Role; if (role.FactType == mySourceShape.AssociatedFactType) { // Add or remove the role IList<Role> roles = SelectedRoleCollection; int roleIndex = roles.IndexOf(role); bool forceRedraw = false; if (roleIndex >= 0) { // Only remove a role when the control key is down. Otherwise, // there is no way to double-click on a previously selected // role without turning it off, and this is a natural gesture. // Add shift key as well for discoverability. if (0 != (0xff00 & GetKeyState(Keys.ControlKey)) || 0 != (0xff00 & GetKeyState(Keys.ShiftKey))) { forceRedraw = true; roles.RemoveAt(roleIndex); } } else { forceRedraw = true; roles.Add(role); } if (mySourceShape != null) { myPendingOnClickedAction = OnClickedAction.CheckForCommit; } if (forceRedraw) { // Force the shape to redraw Debug.Assert(mySourceShape != null); //source shape should have been set mySourceShape.Invalidate(true); } } } else if (currentElement is ORMDiagram) { base.OnClicked(e); // Let through to allow a cancel } } } }
/// <summary> /// Places each external constraint shape at the point corresponding to the average of all of its referenced shapes. /// Frequency constraints are handled differently, since they apply to only one fact type (but 1 or more roles in that /// fact type) at any time. /// </summary> /// <param name="minimumPoint">The minimum location for new element placement</param> public override void PostLayout(PointD minimumPoint) { ResolveReferences(myConstraintShapes); foreach (LayoutShape shape in myConstraintShapes) { if (!shape.Pinned) { PointD avg = new PointD(0, 0); NodeShape nodeShape = shape.Shape; FrequencyConstraintShape freqShape; FrequencyConstraint constraint; LinkedElementCollection <FactType> relatedFactTypes; int count; if (null != (freqShape = nodeShape as FrequencyConstraintShape) && null != (constraint = freqShape.ModelElement as FrequencyConstraint) && 1 == (relatedFactTypes = constraint.FactTypeCollection).Count) { Diagram diagram = myDiagram; FactType factType = relatedFactTypes[0]; FactTypeShape factTypeShape = null; LayoutShape factTypeLayoutShape = null; foreach (PresentationElement pel in PresentationViewsSubject.GetPresentation(factType)) { FactTypeShape testShape = pel as FactTypeShape; if (testShape != null && testShape.Diagram == diagram) { if (factTypeShape == null) { factTypeShape = testShape; } if (myLayoutShapes.TryGetValue(testShape, out factTypeLayoutShape)) { factTypeShape = testShape; break; } } } LinkedElementCollection <Role> constraintRoles = constraint.RoleCollection; LinkedElementCollection <RoleBase> displayOrder = factTypeShape.DisplayedRoleOrder; DisplayOrientation orientation = factTypeShape.DisplayOrientation; RectangleD shapeBounds = factTypeShape.AbsoluteBounds; SizeD shapeSize = factTypeShape.Size; PointD location = (factTypeLayoutShape != null) ? factTypeLayoutShape.TargetLocation : shapeBounds.Location; count = constraintRoles.Count; double width = shapeSize.Width; double height = shapeSize.Height; for (int i = 0; i < count; i++) { int targetIndex = displayOrder.IndexOf(constraintRoles[i]); switch (orientation) { case DisplayOrientation.Horizontal: avg.Offset((width / (targetIndex + 1)) + location.X, location.Y - height); break; case DisplayOrientation.VerticalRotatedRight: avg.Offset(location.X + width, (height / (targetIndex + 1)) + location.Y); break; case DisplayOrientation.VerticalRotatedLeft: avg.Offset(location.X + width, height - (height / (targetIndex + 1)) + location.Y); break; } } avg.X /= count; avg.Y /= count; } else if (0 != (count = shape.Count)) { double minX = double.MaxValue; double minY = double.MaxValue; double maxX = 0; double maxY = 0; SizeD size; LayoutShapeList relatedShapes = shape.RelatedShapes; // Take the center of farthest bounds as the location. // This is the same as the average for two elements, but // balances more than two elements much better. for (int i = 0; i < count; ++i) { LayoutShape relatedShape = relatedShapes[i]; PointD location = relatedShape.TargetLocation; size = relatedShape.Shape.Size; double x = location.X + size.Width / 2; double y = location.Y + size.Height / 2; minX = Math.Min(minX, x); minY = Math.Min(minY, y); maxX = Math.Max(maxX, x); maxY = Math.Max(maxY, y); } size = nodeShape.Size; avg.X = (maxX + minX) / 2 - size.Width / 2; avg.Y = (maxY + minY) / 2 - size.Height / 2; // Constraints are frequently ending up directly on top of // an ObjectTypeShape, bump them up a bit double bumpAdjust = size.Height * 2; avg.Y -= bumpAdjust; if (avg.Y < minimumPoint.Y) { avg.Y += bumpAdjust + bumpAdjust; } } shape.TargetLocation = avg; } shape.Placed = true; } // Now add the shapes back into the main myLayoutShape list for reflow foreach (LayoutShape shape in myConstraintShapes) { myLayoutShapes.Add(shape); } myConstraintShapes.Clear(); }
/// <summary> /// Sets the isVisible property for the given Role /// </summary> private static void SetRoleNameDisplay(Role role, FactTypeShape parentShape, bool shouldDisplay, bool shouldRemove) { if (!shouldRemove) { Diagram.FixUpDiagram(role.FactType, role); } LinkedElementCollection<PresentationElement> pels = PresentationViewsSubject.GetPresentation(role); int pelCount = pels.Count; for (int i = pelCount - 1; i >= 0; --i) { RoleNameShape rns = pels[i] as RoleNameShape; if (rns != null && (parentShape == null || rns.ParentShape == parentShape)) { if (shouldRemove) { rns.Delete(); } else { if (shouldDisplay) { rns.Show(); } else { rns.Hide(); rns.Size = SizeD.Empty; } } } } }