} // end of UnindentBlock() public void MoveUp() { // If we're already at the top, do nothing. if (Index > 0) { List <ReflexPanel> panels = InGame.inGame.Editor.ActivePanels; // Find the block above this on and swap places with it. int topIndex = Index - 1; while (topIndex > 0) { if (panels[topIndex].Reflex.Indentation <= panels[Index].Reflex.Indentation) { break; } --topIndex; } ReflexBlock topBlock = new ReflexBlock(); topBlock.Init(topIndex); // If the block above this one actually contains this block then // we need to shorten the top block. This can happen if you're // moving a child reflex out of a block. if (Index < topBlock.Index + topBlock.Size) { topBlock.Size = Index - topBlock.Index; } SwapBlocks(this, topBlock); } } // end of MoveUp()
} // end of MoveUp() public void MoveDown() { List <ReflexPanel> panels = InGame.inGame.Editor.ActivePanels; Task task = panels[0].Reflex.Task; // Find the block below this one and swap places with it. int bottomIndex = Index + Size; // If there are no reflexes below this one, there's // no place to go so don;t do anything. if (bottomIndex < panels.Count) { ReflexBlock bottomBlock = new ReflexBlock(); bottomBlock.Init(bottomIndex); SwapBlocks(this, bottomBlock); } } // end of MoveDown()
} // end of class ReflexComparer /// <summary> /// After an action this adjusts the indent level to ensure it's valid. /// </summary> private void ValidateIndent() { List <ReflexPanel> panels = InGame.inGame.Editor.ActivePanels; int max = Index == 0 ? 0 : panels[Index - 1].Reflex.Indentation + 1; while (panels[Index].Reflex.Indentation > max) { Unindent(false); } while (panels[Index].Reflex.Indentation < max && panels[Index].Reflex.Indentation < OriginalIndent) { Indent(false); } // Moving a block may cause the following block to also need to move. // If there are reflexes following this block create a new block and validate it. if (Index + Size < panels.Count) { ReflexBlock block = new ReflexBlock(); block.Init(Index + Size); block.ValidateIndent(); } } // end of ValidateIndent()
} // end of MoveDown() /// <summary> /// Exchanges the position of 2 blocks of reflexes in the current task. /// Also aniamtes the UI. /// Assumes that the camera should end up looking at b0 /// </summary> /// <param name="b0"></param> /// <param name="b1"></param> public void SwapBlocks(ReflexBlock b0, ReflexBlock b1) { List <ReflexPanel> panels = InGame.inGame.Editor.ActivePanels; Task task = panels[0].Reflex.Task; // Why isn't this a constant somewhere??? float heightPanel = panels[0].BoundingBox.Max.Y - panels[0].BoundingBox.Min.Y; // How far to move b0's panels. int steps0 = b0.Index < b1.Index ? b1.Size : -b1.Size; for (int i = b0.Index; i < b0.Index + b0.Size; i++) { panels[i].AnimatePanelMove(-steps0 * heightPanel); } // Move the camera the same amount. InGame.inGame.Editor.MoveCamera(-steps0 * heightPanel); // Move b1's panels. int steps1 = b1.Index < b0.Index ? b0.Size : -b0.Size; for (int i = b1.Index; i < b1.Index + b1.Size; i++) { panels[i].AnimatePanelMove(-steps1 * heightPanel); } /* * Debug.Print("before"); * Debug.Print("panels"); * for (int i = 0; i < panels.Count; i++) * { * Debug.Print(panels[i].UniqueNum.ToString() + " " + panels[i].LineNumber.ToString()); * } * Debug.Print("reflexes"); * for (int i = 0; i < task.reflexes.Count; i++) * { * Debug.Print(((Reflex)task.reflexes[i]).UniqueNum.ToString()); * } */ // Now actually swap the panels. Copy the panel refs to // an array and then copy them back in their new position. ReflexPanel[] panelArray = new ReflexPanel[panels.Count]; panels.CopyTo(panelArray); // b0's elements for (int i = 0; i < b0.Size; i++) { panels[b0.Index + i + steps0] = panelArray[b0.Index + i]; } // b1's elements for (int i = 0; i < b1.Size; i++) { panels[b1.Index + i + steps1] = panelArray[b1.Index + i]; } // Now do the same for the reflexes. Reflex[] reflexArray = new Reflex[task.reflexes.Count]; task.reflexes.CopyTo(reflexArray); // b0's elements for (int i = 0; i < b0.Size; i++) { task.reflexes[b0.Index + i + steps0] = reflexArray[b0.Index + i]; } // b1's elements for (int i = 0; i < b1.Size; i++) { task.reflexes[b1.Index + i + steps1] = reflexArray[b1.Index + i]; } // Update line numbers. for (int i = 0; i < panels.Count; i++) { panels[i].LineNumber = i + 1; } // Hack mode... // In the rendering of the editor we need to keep the order of the reflexes // in sync. This is so the mouse hit testing can know which reflex it is // hitting. So, reorder the elements in the renderobject also. // Without doing this, what happens is that the reflexes in the panel // and reflex arrays (already 1 too many) are reordered but the render list // isn't. When the mouse hit testing finds a hit it has no way to associate // that with the actual reflex being hit so we have to rely on its index // in the renderlist. Hence the need to keep them in sync and a warning to // future generations that overly aggressive abstraction will come back to bite you. List <RenderObject> rlist = InGame.inGame.Editor.renderObj.renderList; RenderObject[] rArray = new RenderObject[rlist.Count]; rlist.CopyTo(rArray); // b0's elements for (int i = 0; i < b0.Size; i++) { rlist[b0.Index + i + steps0] = rArray[b0.Index + i]; } // b1's elements for (int i = 0; i < b1.Size; i++) { rlist[b1.Index + i + steps1] = rArray[b1.Index + i]; } /* * Debug.Print("before"); * Debug.Print("panels"); * for (int i = 0; i < panels.Count; i++) * { * Debug.Print(panels[i].UniqueNum.ToString() + " " + panels[i].LineNumber.ToString()); * } * Debug.Print("reflexes"); * for (int i = 0; i < task.reflexes.Count; i++) * { * Debug.Print(((Reflex)task.reflexes[i]).UniqueNum.ToString()); * } */ // Update the active panel to stil point to the same reflex. InGame.inGame.Editor.IndexActivePanel = b0.Index + steps0; // Update the values in the blocks. b0.Index += steps0; b1.Index += steps1; } // end of SwapBlocks()