private int mNextPreferedActiveConnectionIndex = 0; // the prefered active connection index according to the brick library /// <summary> /// Add a new named group which has the specified partNumber on the specifier layer, and connected it to /// the specified selectedItem (part or group) using the specified wanted connection for that new part. /// </summary> /// <param name="layer">The layer on which to add the group, and in which the selectedItem is selected</param> /// <param name="selectedItem">The single selected item (this can be a single part or a single group). This parameter cannot be null.</param> /// <param name="partNumber">The number of the named group to add</param> /// <param name="wantedConnexion">The connection index of the group to add that should be used to connect to the selected item, or -1 if you don't care.</param> public AddConnectGroup(LayerBrick layer, Layer.LayerItem selectedItem, string partNumber, int wantedConnexion) { // the selected item should not be null System.Diagnostics.Debug.Assert(selectedItem != null); // save the layer and construct the group mBrickLayer = layer; mGroup = new Layer.Group(partNumber); // get the flat list of bricks from the hierarchical group mBricksInTheGroup = mGroup.getAllLeafItems(); // get the connectable brick among the selection, and also the selected item (in case the selected item is a single group without connections points) LayerBrick.Brick selectedBrick = layer.getConnectableBrick(); LayerBrick.Brick brickToConnectInAddedGroup = null; // check if we can attach the group to the unique selected object if ((selectedBrick != null) && selectedBrick.HasConnectionPoint) { // find the brick of the group that will be connected to the selected brick brickToConnectInAddedGroup = findBrickToConnectAndSetBestConnectionPointIndex(selectedItem, ref wantedConnexion); } // check if the brick to connect is valid and has connection point if ((brickToConnectInAddedGroup != null) && brickToConnectInAddedGroup.HasConnectionPoint) { // after setting the active connection point index from which this brick will be attached, // get the prefered index from the library mNextPreferedActiveConnectionIndex = BrickLibrary.Instance.getConnectionNextPreferedIndex(partNumber, wantedConnexion); // Compute the orientation of the bricks float newOrientation = AddConnectBrick.sGetOrientationOfConnectedBrick(selectedBrick, brickToConnectInAddedGroup); newOrientation -= brickToConnectInAddedGroup.Orientation; // Rotate all the bricks of the group first before translating RotateBrickOnPivotBrick rotateBricksAction = new RotateBrickOnPivotBrick(layer, mBricksInTheGroup, newOrientation, brickToConnectInAddedGroup); rotateBricksAction.MustUpdateBrickConnectivity = false; rotateBricksAction.redo(); // compute the translation to add to all the bricks PointF translation = new PointF(selectedBrick.ActiveConnectionPosition.X - brickToConnectInAddedGroup.ActiveConnectionPosition.X, selectedBrick.ActiveConnectionPosition.Y - brickToConnectInAddedGroup.ActiveConnectionPosition.Y); mGroup.translate(translation); } else { // and just compute the position to the right of the selected item PointF position = selectedItem.Position; position.X += selectedItem.DisplayArea.Width; mGroup.Position = position; // the reassing the selected brick with the first brick of the group if the selected item is a group // so that the brick index can correctly be set if (selectedItem.IsAGroup) { selectedBrick = (selectedItem as Layer.Group).getAllLeafItems()[0] as LayerBrick.Brick; } else { selectedBrick = selectedItem as LayerBrick.Brick; } } // set the index of the group in the list just after the selected brick if (selectedBrick != null) { mInsertIndex = layer.BrickList.IndexOf(selectedBrick) + 1; } }
public void addConnectBrick(string partNumber, int connexion) { BrickAddability canAdd = canAddBrick(partNumber); if (canAdd == BrickAddability.YES) { LayerBrick brickLayer = Map.sInstance.SelectedLayer as LayerBrick; if ((brickLayer != null) && (brickLayer.getConnectableBrick() != null)) { // create the correct action depending if the part is a group or not Actions.Action action = null; if (BrickLibrary.Instance.isAGroup(partNumber)) action = new AddConnectGroup(brickLayer, partNumber, connexion); else action = new AddConnectBrick(brickLayer, partNumber, connexion); // and add the action in the manager ActionManager.Instance.doAction(action); } } else giveFeedbackForNotAddingBrick(canAdd); }
public RotateBrick(LayerBrick layer, List <Layer.LayerItem> bricks, int rotateSteps, bool forceKeepLastCenter) { // compute the default rotation angle, used if no bricks in the list is connected to something else float angle = MapData.Layer.CurrentRotationStep * rotateSteps; // now check if we can find any brick in the list which is connected to another // brick not in the list: in that case we don't care about the rotation step, // we rotate the group of brick such as it can connect with its next connexion point. // we do this first because maybe it will invalidate the flag sLastCenterIsValid // first we gather all the free connections or those linked with bricks outside of the list of brick FreeConnectionSet externalConnectionSet = new FreeConnectionSet(); // all the connection connected to external bricks FreeConnectionSet availableConnectionSet = new FreeConnectionSet(); // all the possible connections that can be used to link to one external brick foreach (Layer.LayerItem item in bricks) { LayerBrick.Brick brick = item as LayerBrick.Brick; if (brick.HasConnectionPoint) { foreach (LayerBrick.Brick.ConnectionPoint connection in brick.ConnectionPoints) { if (connection.IsFree) { availableConnectionSet.add(connection); } else if (!bricks.Contains(connection.ConnectionLink.mMyBrick)) { availableConnectionSet.add(connection); externalConnectionSet.add(connection); } } } } // get the biggest group of external connection among all the available types, and also get its type int chosenConnexionType = BrickLibrary.ConnectionType.DEFAULT; List <LayerBrick.Brick.ConnectionPoint> externalConnectionList = externalConnectionSet.getBiggestList(out chosenConnexionType); // check if there is any external connection on which we should rotate if (externalConnectionList.Count > 0) { // in that case we don't use the static center sLastCenterIsValid = false; // for now, without a lot of imagination, take the first connection of the list mOldConnectionPoint = externalConnectionList[0]; // store the connection position mConnexionPosition = mOldConnectionPoint.PositionInStudWorldCoord; // get the fixed brick, the external brick on the other side of the chosen connection LayerBrick.Brick fixedBrick = mOldConnectionPoint.ConnectedBrick; int fixedBrickConnectionIndex = mOldConnectionPoint.ConnectionLink.Index; // get the same list but for available connections List <LayerBrick.Brick.ConnectionPoint> availableConnectionList = availableConnectionSet.getListForType(chosenConnexionType); // check in which direction and how many connection we should jump bool rotateCW = (rotateSteps < 0); int nbSteps = Math.Abs(rotateSteps); // get the index of the chosen connection in the available connection list int index = availableConnectionList.IndexOf(mOldConnectionPoint); // start from it then count forward or backward a certain number of connections // depending on the number of steps and the rotation direction if (rotateCW) { index -= (nbSteps % availableConnectionList.Count); if (index < 0) { index += availableConnectionList.Count; } } else { index += (nbSteps % availableConnectionList.Count); if (index >= availableConnectionList.Count) { index -= availableConnectionList.Count; } } // finally get the new connection from the chosen index mNewConnectionPoint = availableConnectionList[index]; // compute the angle to rotate LayerBrick.Brick newConnectedBrick = mNewConnectionPoint.mMyBrick; angle = AddConnectBrick.sGetOrientationOfConnectedBrick(fixedBrick, fixedBrickConnectionIndex, newConnectedBrick, mNewConnectionPoint.Index) - newConnectedBrick.Orientation; } // then call the normal constructor commonConstructor(layer, bricks, angle, forceKeepLastCenter); }