// If s is immediately adjacent to (shares a border with) us, then add it to the // appropriate direction list. If s is not "touching" us, then it will not get added to // any list. s can be added to at most one list (hence use of "else if" instead of just // a sequence of "if's"). public void AddDirectionTo(SnagScreen s) { if ((R.Right == s.R.Left) && GeometryUtil.OverlapY(R, s.R)) { ToRight.Add(s); } else if ((R.Left == s.R.Right) && GeometryUtil.OverlapY(R, s.R)) { ToLeft.Add(s); } else if ((R.Top == s.R.Bottom) && GeometryUtil.OverlapX(R, s.R)) { Above.Add(s); } else if ((R.Bottom == s.R.Top) && GeometryUtil.OverlapX(R, s.R)) { Below.Add(s); } }
// May want to update the above routine, which arbitrarily selects the monitor that // happens to come first in the for() loop. We should probably do a little extra work, // and select the monitor that is closest to the mouse position. // Find the monitor that is closest to the point. //public static SnagScreen ScreenInDirection() //{ //} // Find the best screen to "wrap" around the cursor, either horizontally or // vertically. We consider only the "OuterMost" screens. For instance, if // the mouse is moving to the left, we consider only the screens in the // RightMost[] array. public static SnagScreen WrapScreen(Point Dir, Point Cursor) { int DistClosest = int.MaxValue; SnagScreen WS = null; // Our "wrap screen". if (Dir.X != 0) { // Find closest Left- or Right-most screen, in Y direction. foreach (var S in (Dir.X == 1 ? LeftMost : RightMost)) { int dist = Math.Abs(GeometryUtil.OutsideYDistance(S.R, Cursor)); if (dist < DistClosest) { DistClosest = dist; WS = S; } } return(WS); } // We should never get here, but if we do, just return the first screen. return(All[0]); }
// CheckJumpCursor() returns TRUE, ONLY if the cursor is "stuck". By "stuck" we // specifically mean that the user is trying to move the mouse beyond the boundaries of // the screen currently containing the cursor. This is determined when the *current* // cursor position does not equal the *previous* mouse position. If there is another // adjacent screen (or a "wrap around" screen), then we can consider moving the mouse // onto that screen. // // Note that this is ENTIRELY a *GEOMETRIC* method. Screens are "rectangles", and the // cursor and mouse are "points." The mouse/cursor hardware interaction (obtaining // current mouse and cursor information) is handled in routines further below, and any // Screen changes are handled by the DisplaySettingsChanged event. There are no // hardware or OS/Win32 references or interactions here. private bool CheckJumpCursor(Point mouse, Point cursor, out Point NewCursor) { NewCursor = cursor; // Default is to not move cursor. // Gather pertinent information about cursor, mouse, screens. SnagScreen cursorScreen = SnagScreen.WhichScreen(cursor); SnagScreen mouseScreen = SnagScreen.WhichScreen(mouse); bool IsStuck = (cursor != LastMouse) && (mouseScreen != cursorScreen); Point StuckDirection = GeometryUtil.OutsideDirection(cursorScreen.R, mouse); Debug.WriteLine($" StuckDirection/Distance{StuckDirection}/{GeometryUtil.OutsideDistance(cursorScreen.R, mouse)} " + $"cur_mouse:{mouse} prev_mouse:{LastMouse} ==? cursor:{cursor} (OnMon#{cursorScreen}/{mouseScreen}) " + $"#UnSnags {NJumps} {(IsStuck ? "--STUCK--" : " ")} "); LastMouse = mouse; // Let caller know we did NOT jump the cursor. if (!IsStuck) { return(false); } SnagScreen jumpScreen = SnagScreen.ScreenInDirection(StuckDirection, cursorScreen.R); // If the mouse "location" (which can take on a value beyond the current // cursor screen) has a value, then it is "within" another valid screen // bounds, so just jump to it! if (mouseScreen != null) { if (!IsUnstickEnabled) { return(false); } NewCursor = mouse; } else if (jumpScreen != null) { if (!IsJumpEnabled) { return(false); } NewCursor = jumpScreen.R.ClosestBoundaryPoint(cursor); } else if (StuckDirection.X != 0) { if (!IsScreenWrapEnabled) { return(false); } SnagScreen wrapScreen = SnagScreen.WrapScreen(StuckDirection, cursor); Point wrapPoint = new Point( StuckDirection.X == 1?wrapScreen.R.Left:wrapScreen.R.Right - 1, cursor.Y); // Don't wrap cursor if jumping is disabled and it would need to jump. if (!IsJumpEnabled && !wrapScreen.R.Contains(wrapPoint)) { return(false); } NewCursor = wrapScreen.R.ClosestBoundaryPoint(wrapPoint); } else { return(false); } ++NJumps; Debug.WriteLine("\n -- JUMPED!!! --"); return(true); }