CSharp: Mediator Pattern

 

    /// <summary>
    /// Summary description for Rectangle.
    /// Mediator Pattern中介者模式
    ///20220918
    /// geovindu,Geovin Du,塗聚文
    /// </summary>
    public class Rectangle
    {
        /// <summary>
        /// 
        /// </summary>
        private int xp, yp, wr, hr;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="w"></param>
        /// <param name="h"></param>
        public Rectangle(int x, int y, int w, int h)
        {
            xp = x;
            yp = y;
            wr = w;
            hr = h;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="w"></param>
        /// <param name="h"></param>
        public Rectangle(float x, float y, float w, float h)
        {
            xp = (int)x;
            yp = (int)y;
            wr = (int)w;
            hr = (int)h;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public bool contains(int x, int y)
        {
            bool cn = xp <= x && x <= xp + wr;
            cn = cn && yp <= y && y <= yp + hr;
            return cn;
        }
        /// <summary>
        /// 
        /// </summary>
        public int x
        {
            get
            {
                return xp;
            }
            set
            {
                xp = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public int y
        {
            get
            {
                return yp;
            }
            set
            {
                yp = value;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public int w
        {
            get
            {
                return wr;
            }
            set
            {
                wr = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public int h
        {
            get
            {
                return hr;
            }
            set
            {
                hr = value;
            }
        }
    }

  

   /// <summary>
    /// Summary description for Memento.
    /// Mediator Pattern中介者模式
    ///20220918
    /// geovindu,Geovin Du,塗聚文
    /// </summary>
    public class Memento
    {
        private int x, y, w, h;
        /// <summary>
        /// 
        /// </summary>
        private Rectangle rect;
        /// <summary>
        /// 
        /// </summary>
        private VisRectangle visRect;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="vrect"></param>
        public Memento(VisRectangle vrect)
        {
            visRect = vrect;
            rect = visRect.rects;
            x = rect.x;
            y = rect.y;
            w = rect.w;
            h = rect.h;
        }
        /// <summary>
        /// 
        /// </summary>
        public void restore()
        {
            rect.x = x;
            rect.y = y;
            rect.h = h;
            rect.w = w;
            visRect.rects = rect;
        }
    }

  

    /// <summary>
    /// Summary description for VisRectangle.'
    /// Mediator Pattern中介者模式
    ///20220918
    /// geovindu,Geovin Du,塗聚文
    /// </summary>
    public class VisRectangle
    {
        private int x, y, w, h;
        private const int VSIZE = 30;
        private const int HSIZE = 50;
        private Rectangle rect;
        private bool selected;
        private Pen bPen;
        private SolidBrush bBrush;
        //、
        public VisRectangle(int xp, int yp)
        {
            x = xp; y = yp;
            w = HSIZE; h = VSIZE;
            saveAsRect();
            bPen = new Pen(Color.Black);
            bBrush = new SolidBrush(Color.Black);
        }
        
        /// <summary>
        /// used by Memento for saving and restoring state
        /// </summary>
        internal Rectangle rects
        {
            get
            {
                return rect;
            }
            set
            {
                x = value.x;
                y = value.y;
                w = value.w;
                h = value.h;
                saveAsRect();
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="b"></param>
        public void setSelected(bool b)
        {
            selected = b;
        }
      
        /// <summary>
        /// move to new position
        /// </summary>
        /// <param name="xp"></param>
        /// <param name="yp"></param>
        public void move(int xp, int yp)
        {
            x = xp;
            y = yp;
            saveAsRect();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="g"></param>
        public void draw(Graphics g)
        {
            //draw rectangle
            g.DrawRectangle(bPen, x, y, w, h);

            if (selected)
            {   //draw handles
                g.FillRectangle(bBrush, x + w / 2, y - 2, 4, 4);
                g.FillRectangle(bBrush, x - 2, y + h / 2, 4, 4);
                g.FillRectangle(bBrush, x + (w / 2), y + h - 2, 4, 4);
                g.FillRectangle(bBrush, x + (w - 2), y + (h / 2), 4, 4);
            }
        }

        /// <summary>
        /// return whether point is inside rectangle
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public bool contains(int x, int y)
        {
            return rect.contains(x, y);
        }
  
        /// <summary>
        /// create Rectangle object from new position
        /// </summary>
        private void saveAsRect()
        {
            rect = new Rectangle(x, y, w, h);
        }
    }

  

   /// <summary>
    /// Mediates events between buttonsb
    /// Mediator Pattern中介者模式
    ///20220918
    /// geovindu,Geovin Du,塗聚文
    /// </summary>
    public class Mediator
    {
        private bool startRect;
        private bool rectSelected;
        private ArrayList drawings;
        private PictureBox canvas;
        private int selectedIndex;
        private CareTaker caretakr;
        private RectButton rect;
        private VisRectangle v;
        private VisRectangle[] draw_ings;	//used only to make clearer UML diagram
        /// <summary>
        /// 
        /// </summary>
        /// <param name="p"></param>
        public Mediator(PictureBox p)
        {
            startRect = false;
            rectSelected = false;

            drawings = new ArrayList();
            caretakr = new CareTaker(drawings);
            canvas = p;
        }
        /// <summary>
        /// 
        /// </summary>
        public void startRectangle()
        {
            startRect = true;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public void createRect(int x, int y)
        {
            unpick();         //make sure no rectangle is selected
            if (startRect)
            {  //if rect button is depressed
                int count = drawings.Count;
                caretakr.Add(count);  //Save previous drawing list size
                v = new VisRectangle(x, y);    //create a rectangle
                drawings.Add(v);            //add new element to list
                startRect = false;          //done with this rectangle
                rect.setSelected(false);    //unclick button
                canvas.Refresh();
            }
            else
                pickRect(x, y);   //if not pressed look for rect to select
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="rb"></param>
        public void registerRectButton(RectButton rb)
        {
            rect = rb;
        }
        /// <summary>
        /// 
        /// </summary>
        public void unpick()
        {
            if (rectSelected && (selectedIndex >= 0) && (selectedIndex < drawings.Count))
            {
                VisRectangle vis = (VisRectangle)drawings[selectedIndex];
                vis.setSelected(false);
                selectedIndex = -1;
                rectSelected = false;
                canvas.Refresh();
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public void pickRect(int x, int y)
        {
            //save current selected rectangle
            //to avoid double save of undo
            int lastPick = -1;
            if (selectedIndex >= 0)
            {
                lastPick = selectedIndex;
            }
            unpick();  //undo any selection
            //see if one is being selected
            for (int i = 0; i < drawings.Count; i++)
            {
                v = (VisRectangle)drawings[i];
                if (v.contains(x, y))
                { //did click inside a rectangle
                    selectedIndex = i;     //save it
                    rectSelected = true;
                    if (selectedIndex != lastPick)
                    { //but don't save twice
                        caretakr.rememberPosition(v);
                    }
                    v.setSelected(true);    //turn on handles
                    repaint();          //and redraw
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public void clear()
        {
            drawings = new ArrayList();
            caretakr.clear(drawings);
            rectSelected = false;
            selectedIndex = 0;
            repaint();
        }
        /// <summary>
        /// 
        /// </summary>
        private void repaint()
        {
            canvas.Refresh();
        }
        /// <summary>
        /// 
        /// </summary>
        public void undo()
        {
            caretakr.undo();
            repaint();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="g"></param>
        public void reDraw(Graphics g)
        {
            for (int i = 0; i < drawings.Count; i++)
            {
                VisRectangle v = (VisRectangle)drawings[i];
                v.draw(g);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public void drag(int x, int y)
        {
            if (rectSelected)
            {
                VisRectangle v = (VisRectangle)drawings[selectedIndex];
                if (v.contains(x, y))
                {
                    v.move(x, y);
                    repaint();
                }
            }
        }
    }

  

  /// <summary>
    /// Command interface
    /// Mediator Pattern中介者模式
    ///20220918
    /// geovindu,Geovin Du,塗聚文
    /// </summary>
    public interface Command
    {
        void Execute();
    }

  

   /// <summary>
    /// Summary description for CareTaker.
    /// Mediator Pattern中介者模式
    ///20220918
    /// geovindu,Geovin Du,塗聚文
    /// </summary>
    public class CareTaker
    {
        private ArrayList drawings, undoList;
        private Memento mem;
        private VisRectangle[] draw_ings; //used only to make UML clearer
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dcol"></param>
        public CareTaker(ArrayList dcol)
        {
            clear(dcol);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="vr"></param>
        public void rememberPosition(VisRectangle vr)
        {
            mem = new Memento(vr);
            undoList.Add(mem);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="drw"></param>
        public void clear(ArrayList drw)
        {
            drawings = drw;
            undoList = new ArrayList();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="intg"></param>
        public void Add(int intg)
        {
            undoList.Add(intg);
        }
        /// <summary>
        /// 
        /// </summary>
        public void removeDrawing()
        {
            drawings.RemoveAt(drawings.Count - 1);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="mem"></param>
        public void remove(Memento mem)
        {
            mem.restore();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="intg"></param>
        public void remove(int intg)
        {
            removeDrawing();
        }
        /// <summary>
        /// 
        /// </summary>
        public void undo()
        {
            if (undoList.Count > 0)
            {
                int last = undoList.Count - 1;
                object obj = undoList[last];
                try
                {
                    Memento mem = (Memento)obj;
                    remove(mem);
                }
                catch (Exception)
                {
                    removeDrawing();
                }
                undoList.RemoveAt(last);
            }
        }
    }

  

   /// <summary>
    /// Mediator Pattern中介者模式
    ///20220918
    /// geovindu,Geovin Du,塗聚文
    /// </summary>
    public partial class ClrButton : System.Windows.Forms.Button, Command
    {
        /// <summary>
        /// 
        /// </summary>
        private Mediator med;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="md"></param>
        public ClrButton(Mediator md)
        {
            InitializeComponent();
            med = md;

        }

        /// <summary>
        /// 
        /// </summary>
        public void Execute()
        {
            med.clear();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="container"></param>
        public ClrButton(IContainer container)
        {
            container.Add(this);

            InitializeComponent();
        }
    }

  

    /// <summary>
    /// Mediator Pattern中介者模式
    ///20220918
    /// geovindu,Geovin Du,塗聚文
    /// </summary>
    public partial class RectButton : System.Windows.Forms.ToolBarButton, Command 
    {
        private ToolBarButton bt;
        private Mediator med;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="md"></param>
        /// <param name="tb"></param>
        public RectButton(Mediator md, ToolBarButton tb)
        {
            InitializeComponent();

            med = md;
            bt = tb;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sel"></param>
        public void setSelected(bool sel)
        {
            bt.Pushed = sel;
        }
        /// <summary>
        /// 
        /// </summary>
        public void Execute()
        {
            if (bt.Pushed)
                med.startRectangle();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="container"></param>
        public RectButton(IContainer container)
        {
            container.Add(this);

            InitializeComponent();
        }
    }

  

    /// <summary>
    /// Mediator Pattern中介者模式
    ///20220918
    /// geovindu,Geovin Du,塗聚文
    /// </summary>
    public partial class UndoButton : System.Windows.Forms.ToolBarButton, Command 
    {


        private Mediator med;
        private ToolBarButton ubutton;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="md"></param>
        /// <param name="but"></param>
        public UndoButton(Mediator md, ToolBarButton but)
        {
            InitializeComponent();
            med = md;
            ubutton = but;
        }
        /// <summary>
        /// 
        /// </summary>
        public void Execute()
        {
            med.undo();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="container"></param>
        public UndoButton(IContainer container)
        {
            container.Add(this);

            InitializeComponent();
        }
    }

  

調用:

    /// <summary>
    /// Mediator Pattern
    /// Mediator Pattern中介者模式
    ///20220918
    /// geovindu,Geovin Du,塗聚文
    /// </summary>
    public partial class MediatorPatternForm : Form
    {

        private bool mouse_down;
        private Mediator med;
        private Hashtable commands;

        //-----
        private void init()
        {
            med = new Mediator(pic);     //create Mediator
            commands = new Hashtable();  //and Hash table
            //create the command objectsb
            RectButton rbutn = new RectButton(med, tbar.Buttons[0]);
            UndoButton ubutn = new UndoButton(med, tbar.Buttons[1]);
            ClrButton clrbutn = new ClrButton(med);
            med.registerRectButton(rbutn);
            //add them to the hashtable using the button hash values
            commands.Add(btRect.GetHashCode(), rbutn);
            commands.Add(btUndo.GetHashCode(), ubutn);
            commands.Add(btClear.GetHashCode(), clrbutn);
            pic.Paint += new PaintEventHandler(paintHandler);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void paintHandler(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            med.reDraw(g);
        }		

        /// <summary>
        /// 
        /// </summary>
        public MediatorPatternForm()
        {
            InitializeComponent();
            init();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MediatorPatternForm_Load(object sender, EventArgs e)
        {

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tbar_ButtonClick(object sender, ToolBarButtonClickEventArgs e)
        {
            ToolBarButton tbutn = e.Button;
            Command comd = (Command)commands[tbutn.GetHashCode()];
            comd.Execute();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pic_MouseDown(object sender, MouseEventArgs e)
        {
            mouse_down = true;
            med.createRect(e.X, e.Y);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pic_MouseMove(object sender, MouseEventArgs e)
        {
            if (mouse_down)
                med.drag(e.X, e.Y);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pic_MouseUp(object sender, MouseEventArgs e)
        {
            mouse_down = false;
        }
    }

  

輸出:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章