diff --git a/UI/Controls/InstructionPanel.xaml b/UI/Controls/InstructionPanel.xaml index 01bcefd..3f5aaa2 100644 --- a/UI/Controls/InstructionPanel.xaml +++ b/UI/Controls/InstructionPanel.xaml @@ -32,7 +32,8 @@ diff --git a/UI/Controls/InstructionPanel.xaml.cs b/UI/Controls/InstructionPanel.xaml.cs index 37ce4c1..7f08c14 100644 --- a/UI/Controls/InstructionPanel.xaml.cs +++ b/UI/Controls/InstructionPanel.xaml.cs @@ -15,23 +15,42 @@ namespace iRobotGUI.Controls { - /// - /// Interaction logic for InstructionPanel.xaml - /// - public partial class InstructionPanel : UserControl - { - public InstructionPanel() - { - InitializeComponent(); - } + /// + /// Interaction logic for InstructionPanel.xaml + /// + public partial class InstructionPanel : UserControl + { - private void MouseMove_General(object sender, MouseEventArgs e) - { - Image dragSource = sender as Image; - if (e.LeftButton == MouseButtonState.Pressed) - { - DragDrop.DoDragDrop(sender as Image, dragSource.Tag, DragDropEffects.Copy); - } - } - } + public delegate void AddNewInstructionEventHandler(string opcode); + + /// + /// A instruction image is double clicked and should be added to the program list. + /// + public event AddNewInstructionEventHandler AddNewInstruction; + + public InstructionPanel() + { + InitializeComponent(); + } + + private void Image_MouseMove(object sender, MouseEventArgs e) + { + Image dragSource = sender as Image; + if (e.LeftButton == MouseButtonState.Pressed) + { + DragDrop.DoDragDrop(dragSource, dragSource.Tag, DragDropEffects.Copy); + } + + } + + private void Image_MouseDown(object sender, MouseButtonEventArgs e) + { + Image dragSource = sender as Image; + if (e.ChangedButton == MouseButton.Left && e.ClickCount == 2) + { + if (AddNewInstruction != null) + AddNewInstruction(dragSource.Tag.ToString()); + } + } + } } diff --git a/UI/Controls/ProgramList.xaml b/UI/Controls/ProgramList.xaml index 4f4b1e2..bd672d3 100644 --- a/UI/Controls/ProgramList.xaml +++ b/UI/Controls/ProgramList.xaml @@ -9,9 +9,9 @@ RenderOptions.BitmapScalingMode="HighQuality"> - - - + + + @@ -26,7 +26,7 @@ - + diff --git a/UI/Controls/ProgramList.xaml.cs b/UI/Controls/ProgramList.xaml.cs index 896490f..8113eac 100644 --- a/UI/Controls/ProgramList.xaml.cs +++ b/UI/Controls/ProgramList.xaml.cs @@ -71,6 +71,14 @@ public string Description /// public partial class ProgramList : UserControl { + + public delegate void ProgramListEventHandler(); + public delegate void SelectedInstructionChangedEventHandler(string insString); + + public event ProgramListEventHandler ProgramChanged; + public event ProgramListEventHandler ClipboardChanged; + public event SelectedInstructionChangedEventHandler SelectedInstructionChanged; + #region data private ListViewDragDropManager dragMgr; @@ -181,6 +189,7 @@ void listView_Drop(object sender, DragEventArgs e) int item = pvm[oldIndex]; pvm.Remove(item); pvm.Insert(newIndex, item); + listViewProgram.SelectedIndex = newIndex; UpdateContent(); e.Effects = DragDropEffects.Move; @@ -193,29 +202,52 @@ void listView_Drop(object sender, DragEventArgs e) string op = (string)e.Data.GetData(DataFormats.StringFormat); - Instruction newIns = Instruction.CreatDefaultFromOpcode(op); + InsertNewInstruction(newIndex, op); + } + } + + /// + /// Insert a new instruction at specified index and update the content. + /// + /// The zero-base index at which the new instruction should be inserted. + /// The opcode of the instruction. + public void InsertNewInstruction(int index, string opCode) + { + Instruction newIns = Instruction.CreatDefaultFromOpcode(opCode); - if (newIns != null) + if (newIns != null) + { + if (opCode == Instruction.IF || opCode == Instruction.LOOP) { - if (op == Instruction.IF || op == Instruction.LOOP) - { - // Add HLProgram for IF and LOOP. - pvm.InsertSubProgram(newIndex, HLProgram.GetDefaultIfLoopBlock(newIns)); - } - else - { - // Add single Instruction. - pvm.InsertInstruction(newIndex, newIns); - } + // Add HLProgram for IF and LOOP. + pvm.InsertSubProgram(index, HLProgram.GetDefaultIfLoopBlock(newIns)); + } + else + { + // Add single Instruction. + pvm.InsertInstruction(index, newIns); } - UpdateContent(); - listViewProgram.SelectedIndex = newIndex; + listViewProgram.SelectedIndex = index; + + // To ensure that the selected item is visible. + listViewProgram.ScrollIntoView(listViewProgram.SelectedItem); + if (Properties.Settings.Default.PopupWindowForNewIns) - ShowParamWindow(newIndex); + ShowParamWindow(index); } } + /// + /// Add a new instruction to the end of the list. + /// + /// The opcode of the instruction. + public void AddNewInstruction(string opCode) + { + int index = pvm.Count; + InsertNewInstruction(index, opCode); + } + #endregion // NewlistView_Drop #endregion // event handler @@ -223,7 +255,7 @@ void listView_Drop(object sender, DragEventArgs e) #region private operations /// - /// Update content in ProgramList accordint to pvm + /// Update content in ProgramList according to pvm /// private void UpdateContent() { @@ -234,7 +266,7 @@ private void UpdateContent() for (int i = 0; i < pvm.Count; i++) { - Instruction ins = pvm.GetInstruction(pvm[i]); + Instruction ins = pvm.GetInstruction(i); //Image icon = GetImageFromInstruction(ins); //DisplayItem itemToDisplay = new DisplayItem(icon, TextDescriber.GetTextDescription(ins)); Uri path = GetPathFromInstruction(ins); @@ -245,6 +277,12 @@ private void UpdateContent() } } listViewProgram.SelectedIndex = selectedIndex; + + // Fire ProgramChanged event. + if (ProgramChanged != null) + { + ProgramChanged(); + } } /// @@ -287,11 +325,11 @@ private Uri GetPathFromInstruction(Instruction ins) private void ShowParamWindow(int index) { // The Ins under modification - Instruction selectedIns = pvm.GetInstruction(pvm[index]); + Instruction selectedIns = pvm.GetInstruction(index); if (selectedIns.opcode == Instruction.IF || selectedIns.opcode == Instruction.LOOP) { - HLProgram subProgram = pvm.GetSubProgram(pvm[index]); + HLProgram subProgram = pvm.GetSubProgram(index); // invoke the dialog HLProgram result = DialogInvoker.ShowDialog(subProgram, Window.GetWindow(this)); @@ -309,48 +347,51 @@ private void ShowParamWindow(int index) #endregion // private operations - #region file operations + #region Edit - private void ListCopyExecuted(object sender, ExecutedRoutedEventArgs e) + private void DeleteCanExecute(object sender, CanExecuteRoutedEventArgs e) + { + if (listViewProgram.SelectedIndex != -1) + { + e.CanExecute = true; + } + } + + private void DeleteExecuted(object sender, ExecutedRoutedEventArgs e) + { + RemoveSelection(); + } + + private void CopyExecuted(object sender, ExecutedRoutedEventArgs e) { CopySelection(); } - private void ListCutExecuted(object sender, ExecutedRoutedEventArgs e) + private void CutExecuted(object sender, ExecutedRoutedEventArgs e) { CopySelection(); RemoveSelection(); } - private void ListPasteExecuted(object sender, ExecutedRoutedEventArgs e) + private void PasteExecuted(object sender, ExecutedRoutedEventArgs e) { int newIndex = listViewProgram.SelectedIndex; if (newIndex < 0) newIndex = pvm.Count; - int pvmvalue = Int32.Parse(Clipboard.GetText()); - Instruction ins = pvm.GetInstruction(pvmvalue); - - if (ins.opcode == Instruction.IF || ins.opcode == Instruction.LOOP) - { - pvm.InsertSubProgram(newIndex, pvm.GetSubProgram(pvmvalue)); - } - else - { - String insstring = ins.ToString(); - Instruction newins = new Instruction(insstring); - pvm.InsertInstruction(newIndex, newins); - } + string subProgramString = Clipboard.GetText(); + HLProgram subProgram = new HLProgram(subProgramString); + pvm.InsertSubProgram(newIndex, subProgram); UpdateContent(); } - private void ListCutCopyCanExecute(object sender, CanExecuteRoutedEventArgs e) + private void CutCopyCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = listViewProgram.SelectedIndex >= 0; } - private void ListPasteCanExecute(object sender, CanExecuteRoutedEventArgs e) + private void PasteCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = Clipboard.ContainsText(); } @@ -362,7 +403,12 @@ private void CopySelection() return; Clipboard.Clear(); - Clipboard.SetText(pvm[index].ToString()); + Clipboard.SetText(pvm.GetSubProgram(index).ToString()); + + if (ClipboardChanged != null) + { + ClipboardChanged(); + } } private void RemoveSelection() @@ -372,25 +418,23 @@ private void RemoveSelection() return; // Just remove the pointer. We don't care the source in HLProgram. - pvm.Remove(pvm[index]); + pvm.Remove(index); UpdateContent(); } #endregion // file operations - private void DeleteCanExecute(object sender, CanExecuteRoutedEventArgs e) + private void listViewProgram_SelectionChanged(object sender, SelectionChangedEventArgs e) { - if (listViewProgram.SelectedIndex != -1) + if (SelectedInstructionChanged != null) { - e.CanExecute = true; + if (listViewProgram.SelectedIndex != -1) + SelectedInstructionChanged(pvm.GetSubProgram(listViewProgram.SelectedIndex).ToString()); } } - private void DeleteExecuted(object sender, ExecutedRoutedEventArgs e) - { - RemoveSelection(); - } + } } \ No newline at end of file diff --git a/UI/MainWindow.xaml b/UI/MainWindow.xaml index 66897bf..13a3767 100644 --- a/UI/MainWindow.xaml +++ b/UI/MainWindow.xaml @@ -73,10 +73,10 @@ - + - + @@ -89,7 +89,9 @@ /// The index of pointer. /// The instruction pointed by the pointer. - public Instruction GetInstruction(int item) - { - return program[item]; - } - - /// - /// Get the type of pointer at specified index. The type is determined by the Instruction it points at. - /// - /// - /// - public PointerType GetPointerType(int item) + public Instruction GetInstruction(int pvmIndex) { - if (program[item].opcode == Instruction.IF) - return PointerType.IF; - else if (program[item].opcode == Instruction.LOOP) - return PointerType.LOOP; - else return PointerType.Instruction; + return program[this[pvmIndex]]; } + /// /// Get the sub-program pointed by the pointer at specified index. /// /// The index of pointer. /// The sub-program pointed by the pointer. - public HLProgram GetSubProgram(int startItem) + public HLProgram GetSubProgram(int pvmIndex) { - if (GetPointerType(startItem) == PointerType.IF) + int programIndex = this[pvmIndex]; + Instruction ins = program[programIndex]; + + if (ins.opcode == Instruction.IF) + { + return program.SubProgram(programIndex, program.FindEndIf(programIndex)); + } + else if (ins.opcode == Instruction.LOOP) { - return program.SubProgram(startItem, program.FindEndIf(startItem)); + return program.SubProgram(programIndex, program.FindEndLoop(programIndex)); } - else if (GetPointerType(startItem) == PointerType.LOOP) + else { - return program.SubProgram(startItem, program.FindEndLoop(startItem)); + // A HLProgram with only one instruction. + HLProgram result = new HLProgram(); + result.Add(ins); + return result; } - return null; } /// diff --git a/UI/Windows/IfWindow.xaml b/UI/Windows/IfWindow.xaml index a06cbaf..f7dbbf9 100644 --- a/UI/Windows/IfWindow.xaml +++ b/UI/Windows/IfWindow.xaml @@ -13,7 +13,7 @@ - + diff --git a/UI/Windows/IfWindow.xaml.cs b/UI/Windows/IfWindow.xaml.cs index 6d9e83e..c59811a 100644 --- a/UI/Windows/IfWindow.xaml.cs +++ b/UI/Windows/IfWindow.xaml.cs @@ -72,5 +72,10 @@ public IfWindow() { InitializeComponent(); } + + private void InstructionPanel_AddNewInstruction(string opcode) + { + MessageBox.Show(this, "Use drag-and-drop to add new instructions."); + } } } diff --git a/UI/Windows/LoopWindow.xaml b/UI/Windows/LoopWindow.xaml index 11aa7ab..37366d1 100644 --- a/UI/Windows/LoopWindow.xaml +++ b/UI/Windows/LoopWindow.xaml @@ -14,7 +14,7 @@ - + diff --git a/UI/Windows/LoopWindow.xaml.cs b/UI/Windows/LoopWindow.xaml.cs index 8883a11..7151eb4 100644 --- a/UI/Windows/LoopWindow.xaml.cs +++ b/UI/Windows/LoopWindow.xaml.cs @@ -68,6 +68,11 @@ public HLProgram SubProgram } } + private void InstructionPanel_AddNewInstruction(string opcode) + { + programListLoopBody.AddNewInstruction(opcode); + } + } diff --git a/UnitTests/Util/ProgramViewModelTests.cs b/UnitTests/Util/ProgramViewModelTests.cs index 9fda781..8a2af44 100644 --- a/UnitTests/Util/ProgramViewModelTests.cs +++ b/UnitTests/Util/ProgramViewModelTests.cs @@ -22,11 +22,11 @@ public void GetHLProgramTest() [TestMethod()] public void GetPointerTypeTest() { - var ifExpectPointer = ProgramViewModel.PointerType.IF; - ProgramViewModel pvm = new ProgramViewModel(new HLProgram()); - pvm.InsertInstruction(0, Instruction.CreatDefaultFromOpcode(Instruction.IF)); - var ifActualPointer= pvm.GetPointerType(0); - Assert.AreEqual(ifExpectPointer,ifActualPointer); + //var ifExpectPointer = ProgramViewModel.PointerType.IF; + //ProgramViewModel pvm = new ProgramViewModel(new HLProgram()); + //pvm.InsertInstruction(0, Instruction.CreatDefaultFromOpcode(Instruction.IF)); + //var ifActualPointer= pvm.GetPointerType(0); + //Assert.AreEqual(ifExpectPointer,ifActualPointer); }