internal void SelectEntity(IDiagramEntity entity, Point surfacePoint) { // Groups are treated specially because we can drill-down // into the group. The process of drilling is the first // mouse hit will select the group. The second mouse hit // will select a child, if there's a child at that point. if (entity is IGroup) { if (entity.IsSelected == false) { entity.IsSelected = true; mSelection.Add(entity); } else { IGroup group = entity as IGroup; for (int j = group.Entities.Count - 1; j >= 0; j--) { IDiagramEntity child = group.Entities[j]; if (child.Hit(surfacePoint)) { // Repeat the process because what if this // child is too a group! SelectEntity(child, surfacePoint); group.IsSelected = false; if (mSelection.Contains(group)) { mSelection.Remove(group); } break; } } } } //else if (entity.Group != null) //{ // //entity.Group.IsSelected = true; // //mSelection.Add(entity.Group); //} else { entity.IsSelected = true; mSelection.Add(entity); } }
public static void CollectEntitiesAt(Point surfacePoint) { if (surfacePoint == Point.Empty) { return; } if (Selection.mController == null) { return; } //only change the current selection if the mouse did not hit an already selected element if (mSelection.Count > 0) { foreach (IDiagramEntity entity in mSelection) { if (entity.Rectangle.Contains(surfacePoint)) { return; } } } //here the scene-graph will play a role in the future, //for now we'll keep is simple Selection.Clear(); IConnection con; IShape sh; //we use the paintables here rather than traversing the scene-graph because only //visible things can be collected //We traverse the paintables from top to bottom since the highest z-order //is at the top of the stack. for (int k = Model.Paintables.Count - 1; k >= 0; k--) { IDiagramEntity entity = Model.Paintables[k]; #region we give priority to the connector selection if (typeof(IConnection).IsInstanceOfType(entity)) { con = entity as IConnection; if (con.From.Hit(surfacePoint)) { connector = con.From; connector.IsSelected = true; Invalidate(); return; } if (con.To.Hit(surfacePoint)) { connector = con.To; connector.IsSelected = true; Invalidate(); return; } } else if (typeof(IShape).IsInstanceOfType(entity)) { sh = entity as IShape; foreach (IConnector cn in sh.Connectors) { //if there are connectors attached to the shape connector, the attached ones should be picked up and not the one of the shape if (cn.Hit(surfacePoint) && cn.AttachedConnectors.Count == 0) { connector = cn; connector.IsSelected = true; Invalidate(); //this will invalidate only the selected connector return; //we hit a connector and quit the selection. If the user intended to select the entity it had to be away from the connector! } } } #endregion #region no connector was hit, maybe the entity itself if (entity.Hit(surfacePoint)) { //if the entity is part of an IGroup, the IGroup should be selected //rather than the entity itself //Note that the Group property returns the top group parent and not //just the immediate parent of an entity if (entity.Group != null) { entity.Group.IsSelected = true; mSelection.Add(entity.Group); } else { entity.IsSelected = true; mSelection.Add(entity); } break; } #endregion } RaiseOnNewSelection(); Invalidate(); //Using a full invalidate is rather expensive, so we'll only refresh the current selection //Controller.View.Invalidate(); }
/// <summary> /// Collects the shapes at the given (transformed surface) location. /// The shapes selected in this way are available /// </summary> /// <param name="surfacePoint">The surface point.</param> public void CollectEntitiesAt( Point surfacePoint, bool clearSelectionFirst) { if (surfacePoint == Point.Empty) { return; } if (mModel == null) { return; } // Only change the current selection if the mouse did not hit an // already selected element and the element is not a group. This // allows drilling down into group's children. if (mSelection.Count > 0) { foreach (IDiagramEntity entity in mSelection) { if ((entity.Hit(surfacePoint)) && ((entity is IGroup) == false)) { return; } } } // Clear the current selection only if we're supposed to. if (clearSelectionFirst) { Clear(); } IConnection con; IShape sh; //we use the paintables here rather than traversing the scene-graph because only //visible things can be collected //We traverse the paintables from top to bottom since the highest z-order //is at the top of the stack. for (int k = Model.Paintables.Count - 1; k >= 0; k--) { IDiagramEntity entity = Model.Paintables[k]; #region we give priority to the connector selection if (typeof(IConnection).IsInstanceOfType(entity)) { con = entity as IConnection; if (con.From.Hit(surfacePoint)) { connector = con.From; connector.IsSelected = true; this.RaiseOnNewSelection(); Invalidate(); return; } if (con.To.Hit(surfacePoint)) { connector = con.To; connector.IsSelected = true; this.RaiseOnNewSelection(); Invalidate(); return; } } else if (entity is IGroup) { //should I care about the connectors at this point...? } else if (entity is IShape) { sh = entity as IShape; foreach (IConnector cn in sh.Connectors) { //if there are connectors attached to the shape connector, the attached ones should be picked up and not the one of the shape if (cn.Hit(surfacePoint) && cn.AttachedConnectors.Count == 0) { connector = cn; connector.IsSelected = true; this.RaiseOnNewSelection(); Invalidate(); //this will invalidate only the selected connector return; //we hit a connector and quit the selection. If the user intended to select the entity it had to be away from the connector! } } } #endregion #region no connector was hit, maybe the entity itself if (entity.Hit(surfacePoint)) { SelectEntity(entity, surfacePoint); break; } #endregion } RaiseOnNewSelection(); // Using a full invalidate is rather expensive, so we'll only // refresh the current selection. //Controller.View.Invalidate(); Invalidate(); }