/// <summary>
        /// 点と、点につながるエッジをすべて消す。
        /// </summary>
        private void DeletePoint(PointInf p)
        {
            var ca = new CommandAtomic();

            // 点番号idxに接続しているエッジをすべて消す。
            foreach (var e in mEP.mEdgeList)
            {
                if (e.fromPointIdx == p.Idx ||
                    e.toPointIdx == p.Idx)
                {
                    var cmd = new Command(Command.CommandType.DeleteEdge, null, e);
                    ca.Add(cmd);
                }
            }

            {   // 点idxを消す。
                var cmd = new Command(Command.CommandType.DeletePoint, p, null);
                ca.Add(cmd);
            }

            CommandAtomicDo(ca);

            AddCmdToUndoList(ca);
            UpdateGraphStatus();
        }
 void CommandAtomicUndo(CommandAtomic ca)
 {
     foreach (var c in ca.commandList.Reverse <Command>())
     {
         CommandUndo(c);
     }
 }
 void CommandAtomicDo(CommandAtomic ca)
 {
     foreach (var c in ca.commandList)
     {
         CommandDo(c);
     }
 }
        /// <summary>
        /// 始点決定状態で左クリック:終点を決定する。始点から終点に向かうエッジを追加。終点が新たに始点となる。
        ///   既存点を左クリックしたとき、点の追加を行わずエッジを追加する。
        /// </summary>
        private void PointAddLeftClicked(WWVectorD2 pos)
        {
            if (pos.X < 0 || mCanvas.ActualWidth <= pos.X ||
                pos.Y < 0 || mCanvas.ActualHeight <= pos.Y)
            {
                // Canvas外のクリック。
                return;
            }

            // 始点決定状態。
            System.Diagnostics.Debug.Assert(mPP.mFromPoint != null);

            // 始点決定状態で左クリック:終点を決定する。始点から終点に向かうエッジを追加。終点が新たに始点となる。
            // 既存点を左クリックしたとき、点の追加を行わずエッジを追加する。

            var ca = new CommandAtomic();

            // クリック地点に確定点が存在するか?
            var pInf = mPP.TestHit(pos, mDP.mPointSz);

            if (pInf == null)
            {
                // クリックした場所には確定点は未だ無い。

                // 仮の終点を削除。
                TmpDrawablesRemove((int)TmpDrawablesRemoveOpt.RemoveToPoint);
                mPP.mToPoint = null;

                // 確定の終点を追加する。
                pInf = new PointInf(pos);
                var cmd = new Command(Command.CommandType.AddPoint, pInf, null);
                CommandDo(cmd);
                ca.Add(cmd);
            }
            else if (WWVectorD2.Distance(pInf.xy, mPP.mFromPoint.xy) < 0.5)
            {
                // クリックした点が、始点と同じ点。
                // 特に何もしないで戻る。
                return;
            }

            // クリック地点に始点とは異なる終点pInfが存在する状態。
            // 始点の色を通常色にする。
            mPP.PointChangeColor(mPP.mFromPoint, mDP.mBrush);

            var edge = mEP.FindEdge(mPP.mFromPoint.Idx, pInf.Idx, EdgeProc.FEOption.SamePosition);

            if (edge == null)
            {
                // 始点→終点のエッジが無いので追加。
                var cmd = new Command(Command.CommandType.AddEdge, null, new Edge(mPP.mFromPoint.Idx, pInf.Idx));
                CommandDo(cmd);
                ca.Add(cmd);
            }

            // コマンドが集まったのでアンドゥーリストに足す。
            if (0 < ca.commandList.Count)
            {
                AddCmdToUndoList(ca);
            }

            // クリックした点を新たな始点にする。
            mPP.mFromPoint = pInf;
            mPP.PointChangeColor(mPP.mFromPoint, mDP.mBrightBrush);
        }
 private void AddCmdToUndoList(CommandAtomic ca)
 {
     mCommandList.Add(ca);
     mButtonUndo.IsEnabled = true;
 }