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(); } }