Example #1
0
 protected override void OnMouseUp(MouseEventArgs e)
 {
     bool shiftPressed = ((Control.ModifierKeys & Keys.Shift) != Keys.None);
     bool controlPressed = ((Control.ModifierKeys & Keys.Control) != Keys.None);
     if (!ShowColors && ( shiftPressed|| controlPressed))
         return;
     if (ShowColors && !shiftPressed)
         lastShift = -1;
     if (ShowColors && !controlPressed)
         lastControl = -1;
     float linkLength = scaleSize ;
     int x = e.X - Margin.Left - additionalXMargin;
     int y = e.Y - Margin.Top - additionalYMargin;
     float realX = x/linkLength;
     float realY = y/linkLength;
     int closestEdge = -1;
     int closestCell = -1;
     float distance = 1;
     for (int i = 0; i < mesh.Edges.Count; i++)
     {
         Edge edge = mesh.Edges[i];
         float sx, sy, ex, ey;
         mesh.GetEdgeExtent(edge, out sx, out sy, out ex, out ey);
         float curDist = DistanceToSegment(realX, realY, sx, sy, ex, ey);
         if (curDist <= distance)
         {
             closestEdge = i;
             distance = curDist;
         }
     }
     if (showCellColors)
     {
         for (int i = 0; i < mesh.Cells.Count; i++)
         {
             float cx = 0.0F;
             float cy = 0.0F;
             foreach (int inters in mesh.Cells[i].Intersections)
             {
                 cx += mesh.Intersections[inters].X;
                 cy += mesh.Intersections[inters].Y;
             }
             cx /= mesh.Cells[i].Intersections.Count;
             cy /= mesh.Cells[i].Intersections.Count;
             float distx = cx - realX;
             float disty = cy - realY;
             float curDist = (float)Math.Sqrt(distx * distx + disty * disty);
             if (curDist <= distance)
             {
                 closestEdge = -1;
                 closestCell = i;
                 distance = curDist;
             }
         }
     }
     if (closestEdge != -1)
     {
         if (noToggle && mesh.Edges[closestEdge].State != EdgeState.Empty)
             return;
         if (shiftPressed || controlPressed)
         {
             if (shiftPressed)
             {
                 if (lastShift == -1)
                     lastShift = closestEdge;
                 else
                 {
                     ColorJoinAction colorAction = new ColorJoinAction(mesh, lastShift, closestEdge, true);
                     if (lastShift != closestEdge)
                         undoTree.Do(colorAction);
                     lastShift = -1;
                 }
             }
             else if (controlPressed)
             {
                 if (lastControl == -1)
                     lastControl = closestEdge;
                 else
                 {
                     ColorJoinAction colorAction = new ColorJoinAction(mesh, lastControl, closestEdge, false);
                     if (lastControl != closestEdge)
                         undoTree.Do(colorAction);
                     lastControl = -1;
                 }
             }
             this.Refresh();
             return;
         }
         LoopClickAction action = new LoopClickAction(mesh, closestEdge, e.Button, autoMove, disallowFalseMove, useICInAuto, considerMultipleLoopsInAuto, useColoringInAuto, useCellColoringInAuto, useEdgeRestrictsInAuto, useCellPairsInAuto);
         if (!undoTree.Do(action))
         {
             redEdge = closestEdge;
             Thread thread = new Thread(new ThreadStart(ClearRed));
             thread.IsBackground = true;
             thread.Start();
         }
         else if (noToggle)
         {
             if (MovePerformed != null)
                 MovePerformed(this, new MoveEventArgs(closestEdge, e.Button == MouseButtons.Left));
         }
         else
         {
             bool satisified = true;
             for (int i = 0; i < mesh.Cells.Count; i++)
             {
                 if (mesh.Cells[i].TargetCount >= 0 && mesh.Cells[i].FilledCount != mesh.Cells[i].TargetCount)
                     satisified = false;
             }
             if (satisified)
             {
                 Mesh copy = new Mesh(mesh);
                 try
                 {
                     copy.SolverMethod = SolverMethod.Recursive;
                     copy.UseIntersectCellInteractsInSolver = false;
                     copy.Clear();
                     if (copy.TrySolve() == SolveState.Solved)
                     {
                         bool done = true;
                         for (int i = 0; i < mesh.Edges.Count; i++)
                         {
                             if (copy.SolutionFound.Edges[i].State == EdgeState.Filled)
                             {
                                 if (mesh.Edges[i].State != EdgeState.Filled)
                                     done = false;
                             }
                             else if (mesh.Edges[i].State == EdgeState.Filled)
                                 done = false;
                         }
                         if (done)
                         {
                             allDone = true;
                             if (Solved != null)
                                 Solved(this, EventArgs.Empty);
                             Thread thread = new Thread(new ThreadStart(Done));
                             thread.IsBackground = true;
                             thread.Start();
                         }
                     }
                 }
                 catch
                 {
                 }
             }
         }
         this.Refresh();
     }
     else if (closestCell != -1)
     {
         if (noToggle && mesh.Cells[closestCell].Color != 0)
             return;
         CellClickAction action = new CellClickAction(mesh, closestCell, e.Button);
         undoTree.Do(action);
         this.Refresh();
     }
     base.OnMouseUp(e);
 }
 private void PerformAction(bool? right, int closestEdge, int closestCell)
 {
     if (closestEdge != -1)
     {
         if (markedEdges.Contains(closestEdge))
             return;
         if (noToggle && Mesh.Edges[closestEdge].State != EdgeState.Empty)
             return;
         /*if (shiftPressed || controlPressed)
         {
             if (shiftPressed)
             {
                 if (lastShift == -1)
                     lastShift = closestEdge;
                 else
                 {
                     ColorJoinAction colorAction = new ColorJoinAction(Mesh, lastShift, closestEdge, true);
                     if (lastShift != closestEdge)
                         undoTree.Do(colorAction);
                     lastShift = -1;
                 }
             }
             else if (controlPressed)
             {
                 if (lastControl == -1)
                     lastControl = closestEdge;
                 else
                 {
                     ColorJoinAction colorAction = new ColorJoinAction(Mesh, lastControl, closestEdge, false);
                     if (lastControl != closestEdge)
                         undoTree.Do(colorAction);
                     lastControl = -1;
                 }
             }
             UpdateChildControls();
             return;
         }*/
         LoopClickAction action;
         if (right.HasValue)
         {
             action = new LoopClickAction(Mesh, closestEdge, right.Value, autoMove, disallowFalseMove, useICInAuto, considerMultipleLoopsInAuto, useColoringInAuto, useCellColoringInAuto);
         }
         else
         {
             if (Mesh.Edges[closestEdge].State == lastState)
                 return;
             bool pretendRight = false;
             switch (lastState)
             {
                 case EdgeState.Filled:
                     if (Mesh.Edges[closestEdge].State == EdgeState.Excluded)
                         pretendRight = true;
                     break;
                 case EdgeState.Excluded:
                     if (Mesh.Edges[closestEdge].State == EdgeState.Empty)
                         pretendRight = true;
                     break;
                 case EdgeState.Empty:
                     if (Mesh.Edges[closestEdge].State == EdgeState.Filled)
                         pretendRight = true;
                     break;
             }
             action = new LoopClickAction(Mesh, closestEdge, pretendRight, autoMove, disallowFalseMove, useICInAuto, considerMultipleLoopsInAuto, useColoringInAuto, useCellColoringInAuto);
         }
         if (!undoTree.Do(action))
         {
             /*
             redEdge = closestEdge;
             Thread thread = new Thread(new ThreadStart(ClearRed));
             thread.IsBackground = true;
             thread.Start();
              */
         }
         else if (noToggle)
         {
             /*
             if (MovePerformed != null)
                 MovePerformed(this, new MoveEventArgs(closestEdge, e.Button == MouseButtons.Left));
              * */
         }
         else
         {
             if (right.HasValue)
             {
                 lastState = Mesh.Edges[closestEdge].State;
             }
             bool satisified = true;
             for (int i = 0; i < Mesh.Cells.Count; i++)
             {
                 if (Mesh.Cells[i].TargetCount >= 0 && Mesh.Cells[i].FilledCount != Mesh.Cells[i].TargetCount)
                     satisified = false;
             }
             if (satisified)
             {
                 Mesh copy = new Mesh(Mesh);
                 try
                 {
                     copy.Clear();
                     bool failed = false;
                     if (copy.TrySolve() != SolveState.Solved)
                     {
                         copy.SolverMethod = SolverMethod.Recursive;
                         copy.UseIntersectCellInteractsInSolver = false;
                         copy.UseCellColoringTrials = false;
                         copy.UseCellColoring = true;
                         copy.UseCellPairs = false;
                         copy.UseCellPairsTopLevel = true;
                         copy.UseColoring = true;
                         copy.UseDerivedColoring = true;
                         copy.UseEdgeRestricts = true;
                         copy.UseMerging = true;
                         copy.ConsiderMultipleLoops = true;
                         copy.ColoringCheats = true;
                         if (copy.TrySolve() != SolveState.Solved)
                         {
                             failed = true;
                         }
                     }
                     if (!failed)
                     {
                         bool done = true;
                         for (int i = 0; i < Mesh.Edges.Count; i++)
                         {
                             if (copy.SolutionFound.Edges[i].State == EdgeState.Filled)
                             {
                                 if (Mesh.Edges[i].State != EdgeState.Filled)
                                     done = false;
                             }
                             else if (Mesh.Edges[i].State == EdgeState.Filled)
                                 done = false;
                         }
                         if (done)
                         {
                             FixPosition();
                             copy.FullClear();
                             ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object o) { GenerateNew(copy); }));
                         }
                     }
                 }
                 catch
                 {
                 }
             }
         }
         UpdateChildControls();
     }
     else if (closestCell != -1)
     {
         if (noToggle && Mesh.Cells[closestCell].Color != 0)
             return;
         CellClickAction action = new CellClickAction(Mesh, closestCell, right.Value);
         undoTree.Do(action);
         UpdateChildControls();
     }
 }