UI 1using System; 2using System.Drawing; 3using System.IO; 4using System.Reflection; 5using System.Windows.Forms; 6 7namespace Gof.Test.Memento 8{ 9/**////<summary> 10/// User interface utilities. 11///</summary> 12publicclass UI 13{ 14protected Font _font =new Font("Book Antiqua", 18F); 15publicstaticreadonlyint STANDARD_PAD =10; 16publicstaticreadonly UI NORMAL =new UI(); 17/**////<summary> 18/// Set up a standard font that subclasses can override. 19///</summary> 20publicvirtual Font Font 21{ 22get 23{ 24return _font; 25 } 26 } 27/**////<summary> 28/// Set up a standard pad amount that subclasses can override. 29///</summary> 30publicvirtualint Pad 31{ 32get 33{ 34return STANDARD_PAD; 35 } 36 } 37/**////<summary> 38/// Create a standard Ok! (or affirmation) button. 39///</summary> 40///<returns>a standard Ok! (or affirmation) button</returns> 41publicvirtual Button CreateButtonOk() 42{ 43 Button b = CreateButton(); 44 b.Image = GetImage("rocket-large.gif"); 45 b.Text ="Ok!"; 46return b; 47 } 48/**////<summary> 49/// Create a standard Cancel! (or negation) button. 50///</summary> 51///<returns>a standard Cancel! (or negation) button</returns> 52publicvirtual Button CreateButtonCancel() 53{ 54 Button b = CreateButton(); 55 b.Image = GetImage("rocket-large-down.gif"); 56 b.Text ="Cancel!"; 57return b; 58 } 59 60/**////<summary> 61/// Create a standard button. 62///</summary> 63///<returns>a standard button</returns> 64publicvirtual Button CreateButton() 65{ 66 Button b =new Button(); 67 b.Size =new Size(128, 128); 68 b.ImageAlign = ContentAlignment.TopCenter; 69 b.Font = Font; 70 b.TextAlign = ContentAlignment.BottomCenter; 71return b; 72 } 73/**////<summary> 74/// Create a panel that adds a standard amount of padding around 75/// any controls that are added to it. 76///</summary> 77///<returns>the panel</returns> 78publicvirtual Panel CreatePaddedPanel() 79{ 80 Panel p =new Panel(); 81 p.Dock = DockStyle.Fill; 82 p.DockPadding.All = Pad; 83return p; 84 } 85/**////<summary> 86/// Create a panel that adds a standard amount of padding around 87/// a given control. 88///</summary> 89///<param name="c">the control</param> 90///<returns>the panel</returns> 91publicvirtual Panel CreatePaddedPanel(Control c) 92{ 93 Panel p = CreatePaddedPanel(); 94 p.Controls.Add(c); 95return p; 96 } 97/**////<summary> 98/// Create a group box that wraps a titled border around a 99/// given component. 100///</summary> 101///<param name="title">The words to show in the title border tab</param> 102///<param name="control">The control that the border goes around</param> 103///<returns>A group box panel with a title, wrapped around the 104/// supplied control</returns> 105publicvirtual GroupBox CreateGroupBox( 106 String title, Control control) 107{ 108 GroupBox gb =new GroupBox(); 109 gb.Text = title; 110 gb.Dock = DockStyle.Fill; 111 gb.Controls.Add(control); 112return gb; 113 } 114/**////<summary> 115/// Create a standard grid for displaying, in particular, 116/// database tables. 117///</summary> 118///<returns>A standard data grid</returns> 119publicvirtual DataGrid CreateGrid() 120{ 121 DataGrid g =new DataGrid(); 122 g.Dock = DockStyle.Fill; 123 g.CaptionVisible =false; 124return g; 125 } 126/**////<summary> 127/// Create a standard list, where each list item has an accompanying 128/// image/icon. 129///</summary> 130///<param name="size">the size for images</param> 131///<param name="images">the images</param> 132///<returns>a standard list view</returns> 133publicvirtual ListView CreateListView(Size size, params Image[] images) 134{ 135 ListView lv =new ListView(); 136 lv.Font = Font; 137 lv.View = View.Details; 138 lv.Columns.Add(new ColumnHeader()); 139 lv.Columns[0].Width =-2; // autosize 140 lv.HeaderStyle = ColumnHeaderStyle.None; 141 lv.SmallImageList = CreateImageList(size, images); 142return lv; 143 } 144// Create an ImageList object given the images and the desired 145// size for them. 146protectedvirtual ImageList CreateImageList (Size size, params Image[] images) 147{ 148 ImageList il =new ImageList(); 149 il.ColorDepth = ColorDepth.Depth32Bit; 150 il.ImageSize = size; 151foreach (Image i in images) 152{ 153 il.Images.Add(i); 154 } 155return il; 156 } 157/**////<summary> 158/// This method looks up an image file and returns the image 159/// contained therein. This method expects all images to be 160/// in a path relative to the directory that this assembly 161/// is in, namely ..\images. 162///</summary> 163///<param name="imageName">the image to look up</param> 164///<returns>the image</returns> 165publicstatic Image GetImage(String imageName) 166{ 167return Image.FromFile(Gof.Test.Proxy.DataService.GetFileName("images", imageName)); 168 } 169 } 170}
FacotryModel 1using System; 2using System.Collections; 3using System.Drawing; 4 5namespace Gof.Test.Memento 6{ 7publicclass FactoryModel 8{ 9private Stack _mementos; 10publicevent AddHandler AddEvent; 11publicevent DragHandler DragEvent; 12publicevent RebuildHandler RebuildEvent; 13publicstaticreadonly Point DEFAULT_LOCATION =new Point(10,10); 14public FactoryModel() 15{ 16 _mementos =new Stack(); 17 _mementos.Push(new ArrayList()); 18 } 19publicvoid AddMachine() 20{ 21 IList newLocs =new ArrayList(); 22 Point newP = DEFAULT_LOCATION; 23 newLocs.Add(newP); 24foreach(Point p in (IList)_mementos.Peek()) 25{ 26 newLocs.Add(new Point(p.X,p.Y)); 27 } 28 _mementos.Push(newLocs); 29 30if(AddEvent !=null) 31{ 32 AddEvent(newP); 33 } 34 } 35public IList Locations 36{ 37get 38{ 39return (IList)_mementos.Peek(); 40 } 41 } 42publicvoid Pop() 43{ 44if(_mementos.Count >1) 45{ 46 _mementos.Pop(); 47 } 48if(RebuildEvent !=null) 49{ 50 RebuildEvent(); 51 } 52 } 53/**////<summary> 54/// Move a machine from an old location to a new one. A side 55/// effect is that the new location will be the first in this 56/// model's list of locations. This helps the GUI handle Z order. 57/// In particular, just clicking a machine will move it the the 58/// head of the list and will thus bring it to the "front" of 59/// the display. 60///</summary> 61///<param name="oldP">where the machine was</param> 62///<param name="newP">the new spot for the machine</param> 63publicvoid Drag(Point oldP, Point newP) 64{ 65// put the new location up front so its Z order is on top 66 IList newLocs =new ArrayList(); 67 newLocs.Add(newP); 68// create a new list, copying in all except the dragee 69bool foundDragee =false; 70foreach (Point p in (IList)_mementos.Peek()) 71{ 72if ( !foundDragee && p.Equals(oldP)) 73{ 74 foundDragee =true; 75 } 76else 77{ 78 newLocs.Add(new Point(p.X, p.Y)); 79 } 80 } 81 _mementos.Push(newLocs); 82if (DragEvent !=null) DragEvent(oldP, newP); 83 } 84/**////<summary> 85/// Add a new configuration. 86///</summary> 87///<param name="list">A list of Point objects representing machine locations</param> 88publicvoid Push(IList list) 89{ 90 _mementos.Push(list); 91if (RebuildEvent !=null) RebuildEvent(); 92 } 93/**////<summary> 94/// Return the number of saved configurations. This helps the GUI 95/// decide whether to offer "undo". 96///</summary> 97publicint MementoCount 98{ 99get 100{ 101return _mementos.Count; 102 } 103 } 104 } 105}
VisMediator 1using System; 2using System.Collections; 3using System.Drawing; 4using System.IO; 5using System.Runtime.Serialization.Formatters.Soap; 6using System.Windows.Forms; 7 8namespace Gof.Test.Memento 9{ 10/**////<summary> 11/// This class handles the UI events for the Visualization class 12///</summary> 13publicclass VisMediator 14{ 15protectedint initX; 16protectedint initY; 17protected Point initLocation; 18protectedbool isMouseDown =false; 19 20protected FactoryModel _factoryModel; 21 22/**////<summary> 23/// Create a new mediator for a visualization that uses the provided 24/// factory model. 25///</summary> 26///<param name="m">The model that tracks equipment locations</param> 27public VisMediator(FactoryModel m) 28{ 29 _factoryModel = m; 30 } 31 32// The user clicked "Add" 33internalvoid Add(object sender, System.EventArgs e) 34{ 35 _factoryModel.AddMachine(); 36 } 37 38// The user has clicked "Undo" 39internalvoid Undo(object sender, System.EventArgs e) 40{ 41 _factoryModel.Pop(); 42 } 43 44// A click on a picture box 45internalvoid MouseDown(object sender, MouseEventArgs e) 46{ 47if (e.Button == MouseButtons.Left) 48{ 49 PictureBox pb = (PictureBox) sender; 50 initLocation = pb.Location; 51 initX = Control.MousePosition.X; 52 initY = Control.MousePosition.Y; 53 isMouseDown =true; 54 } 55 } 56 57// A drag while a picture box is clicked 58internalvoid MouseMove(object sender, MouseEventArgs e) 59{ 60if (isMouseDown) 61{ 62 63 PictureBox pb = (PictureBox) sender; 64 pb.Location =new Point(initLocation.X + Control.MousePosition.X - initX, 65 initLocation.Y + Control.MousePosition.Y - initY); 66 } 67 } 68 69// leggo of a picture box. Let the factory model know about this change 70internalvoid MouseUp(object sender, MouseEventArgs e) 71{ 72if (e.Button == MouseButtons.Left) 73{ 74 isMouseDown =false; 75 PictureBox pb = (PictureBox) sender; 76 _factoryModel.Drag(initLocation, pb.Location); 77 } 78 } 79 80// User clicked "Save As" menu item 81internalvoid Save(object sender, System.EventArgs e) 82{ 83 SaveFileDialog d =new SaveFileDialog(); 84if (d.ShowDialog() == DialogResult.OK) 85{ 86using (FileStream fs = File.Create(d.FileName)) 87{ 88new SoapFormatter().Serialize(fs, _factoryModel.Locations); 89 } 90 } 91 } 92 93// User clicked "Restore from" menu item 94internalvoid Restore(object sender, System.EventArgs e) 95{ 96 OpenFileDialog d =new OpenFileDialog(); 97if (d.ShowDialog() == DialogResult.OK) 98{ 99using (FileStream fs = File.Open(d.FileName, FileMode.Open)) 100{ 101 IList list = (IList)(new SoapFormatter().Deserialize(fs)); 102 _factoryModel.Push(list); 103 } 104 } 105 } 106 } 107}
Visualization 1using System; 2using System.Drawing; 3using System.Windows.Forms; 4 5namespace Gof.Test.Memento 6{ 7/**////<summary> 8/// This class provides a visualization of a factory that contains 9/// machines and through which material flows. At present the only 10/// functionality is the ability to create and drag machines. In the 11/// future we'll add operational modeling functions. 12///</summary> 13publicclass Visualization : Form 14{ 15protected UI _ui; 16protected Panel _machinePanel; 17protected Panel _buttonPanel; 18protected Button _addButton; 19protected Button _undoButton; 20protected Image _image = UI.GetImage("machine.png"); 21protected FactoryModel _factoryModel =new FactoryModel(); 22protected VisMediator _mediator; 23 24/**////<summary> 25/// Create a new visualization of a simulated factory. 26///</summary> 27public Visualization(UI ui) 28{ 29 _ui = ui; 30 _factoryModel.AddEvent +=new AddHandler(HandleAdd); 31 _factoryModel.DragEvent +=new DragHandler(HandleDrag); 32 _factoryModel.RebuildEvent +=new RebuildHandler(HandleUndo); 33 _mediator =new VisMediator(_factoryModel); 34 Controls.Add(MachinePanel()); 35 Controls.Add(ButtonPanel()); 36 Text ="Operational Model"; 37 } 38 39// the panel on which we'll drag around machines 40protected Panel MachinePanel() 41{ 42if (_machinePanel ==null) 43{ 44 _machinePanel =new Panel(); 45 _machinePanel.BackColor = Color.White; 46 _machinePanel.Dock = DockStyle.Fill; 47 } 48return _machinePanel; 49 } 50 51// the panel that holds the app's buttons 52protected Panel ButtonPanel() 53{ 54if (_buttonPanel ==null) 55{ 56 _buttonPanel =new Panel(); 57 _buttonPanel.Controls.Add(AddButton()); 58 _buttonPanel.Controls.Add(UndoButton()); 59 _buttonPanel.Dock = DockStyle.Bottom; 60 _buttonPanel.Height = (int)(AddButton().Height *1.10); 61 } 62return _buttonPanel; 63 } 64 65// the "Add" button 66protected Button AddButton() 67{ 68if (_addButton ==null) 69{ 70 _addButton = _ui.CreateButtonOk(); 71 _addButton.Dock = DockStyle.Left; 72 _addButton.Text ="Add"; 73 _addButton.Click +=new System.EventHandler(_mediator.Add); 74 } 75return _addButton; 76 } 77 78// the "Undo" button 79protected Button UndoButton() 80{ 81if (_undoButton ==null) 82{ 83 _undoButton = _ui.CreateButtonCancel(); 84 _undoButton.Dock = DockStyle.Right; 85 _undoButton.Text ="Undo"; 86 _undoButton.Click +=new System.EventHandler(_mediator.Undo); 87 _undoButton.Enabled =false; 88 } 89return _undoButton; 90 } 91 92 93// Add a new machine at the given location 94protectedvoid HandleAdd(Point p) 95{ 96 PictureBox pb = CreatePictureBox(p); 97 MachinePanel().Controls.Add(pb); 98 pb.BringToFront(); 99 UndoButton().Enabled =true; 100 } 101 102// Dragging a machine brings it to the front of the controls 103// in the machine panel, and updates the machine's location 104protectedvoid HandleDrag(Point oldP, Point newP) 105{ 106foreach (PictureBox pb in MachinePanel().Controls) 107{ 108if (pb.Location.Equals(newP)) 109{ 110 pb.BringToFront(); 111return; 112 } 113 } 114 } 115 116// When the user clicks Undo, we rebuild the factory 117// from the model. 118protectedvoid HandleUndo() 119{ 120 MachinePanel().Controls.Clear(); 121foreach (Point p in _factoryModel.Locations) 122{ 123 MachinePanel().Controls.Add(CreatePictureBox(p)); 124 } 125 UndoButton().Enabled = _factoryModel.MementoCount >1; 126 } 127 128// Create a standard picture of a machine 129protected PictureBox CreatePictureBox(Point p) 130{ 131 PictureBox pb =new PictureBox(); 132 pb.Image = _image; 133 pb.Size = _image.Size; 134 pb.MouseDown +=new MouseEventHandler(_mediator.MouseDown); 135 pb.MouseMove +=new MouseEventHandler(_mediator.MouseMove); 136 pb.MouseUp +=new MouseEventHandler(_mediator.MouseUp); 137 pb.Location = p; 138return pb; 139 } 140 } 141}