diff options
Diffstat (limited to 'platform/platform-api/src/com/intellij/ui/ScreenUtil.java')
-rw-r--r-- | platform/platform-api/src/com/intellij/ui/ScreenUtil.java | 124 |
1 files changed, 86 insertions, 38 deletions
diff --git a/platform/platform-api/src/com/intellij/ui/ScreenUtil.java b/platform/platform-api/src/com/intellij/ui/ScreenUtil.java index 75769d25c0db..74fe7bb31108 100644 --- a/platform/platform-api/src/com/intellij/ui/ScreenUtil.java +++ b/platform/platform-api/src/com/intellij/ui/ScreenUtil.java @@ -56,22 +56,14 @@ public class ScreenUtil { } public static Rectangle getMainScreenBounds() { - GraphicsConfiguration graphicsConfiguration = - GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration(); - Rectangle bounds = graphicsConfiguration.getBounds(); - applyInsets(bounds, getScreenInsets(graphicsConfiguration)); - return bounds; + return getScreenRectangle(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice()); } private static Rectangle[] getAllScreenBounds() { - final GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); - final GraphicsDevice[] devices = env.getScreenDevices(); + GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(); Rectangle[] result = new Rectangle[devices.length]; for (int i = 0; i < devices.length; i++) { - GraphicsDevice device = devices[i]; - GraphicsConfiguration configuration = device.getDefaultConfiguration(); - result[i] = new Rectangle(configuration.getBounds()); - applyInsets(result[i], getScreenInsets(configuration)); + result[i] = getScreenRectangle(devices[i]); } return result; } @@ -86,27 +78,7 @@ public class ScreenUtil { } public static Rectangle getScreenRectangle(@NotNull Point p) { - double distance = -1; - Rectangle answer = null; - - Rectangle[] allScreenBounds = getAllScreenBounds(); - for (Rectangle rect : allScreenBounds) { - if (rect.contains(p)) { - return rect; - } - - final double d = findNearestPointOnBorder(rect, p).distance(p.x, p.y); - if (answer == null || distance > d) { - distance = d; - answer = rect; - } - } - - if (answer == null) { - throw new IllegalStateException("It's impossible to determine target graphics environment for point (" + p.x + "," + p.y + ")"); - } - - return answer; + return getScreenRectangle(p.x, p.y); } public static GraphicsDevice getScreenDevice(Rectangle bounds) { @@ -150,11 +122,12 @@ public class ScreenUtil { } private static Rectangle applyInsets(Rectangle rect, Insets i) { - if (i == null) { - return rect; - } - - return new Rectangle(rect.x + i.left, rect.y + i.top, rect.width - (i.left + i.right), rect.height - (i.top + i.bottom)); + return (i == null) + ? new Rectangle(rect) + : new Rectangle(rect.x + i.left, + rect.y + i.top, + rect.width - (i.left + i.right), + rect.height - (i.top + i.bottom)); } public static Insets getScreenInsets(final GraphicsConfiguration gc) { @@ -181,8 +154,83 @@ public class ScreenUtil { return Toolkit.getDefaultToolkit().getScreenInsets(gc); } + /** + * Returns a visible area for the specified graphics device. + * + * @param device one of available devices + * @return a visible area rectangle + */ + private static Rectangle getScreenRectangle(GraphicsDevice device) { + GraphicsConfiguration configuration = device.getDefaultConfiguration(); + return applyInsets(configuration.getBounds(), getScreenInsets(configuration)); + } + + /** + * Finds a device that is the closest to the specified point and + * returns its visible area. + * + * @param x the X coordinate of the specified point + * @param y the Y coordinate of the specified point + * @return a visible area rectangle + */ public static Rectangle getScreenRectangle(int x, int y) { - return getScreenRectangle(new Point(x, y)); + GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(); + if (devices.length == 0) { + return new Rectangle(x, y, 0, 0); + } + if (devices.length == 1) { + return getScreenRectangle(devices[0]); + } + Rectangle[] rectangles = new Rectangle[devices.length]; + for (int i = 0; i < devices.length; i++) { + GraphicsConfiguration configuration = devices[i].getDefaultConfiguration(); + Rectangle bounds = configuration.getBounds(); + rectangles[i] = applyInsets(bounds, getScreenInsets(configuration)); + if (bounds.contains(x, y)) { + return rectangles[i]; + } + } + Rectangle bounds = rectangles[0]; + int minimum = distance(bounds, x, y); + for (int i = 1; i < rectangles.length; i++) { + int distance = distance(rectangles[i], x, y); + if (minimum > distance) { + minimum = distance; + bounds = rectangles[i]; + } + } + return bounds; + } + + /** + * Normalizes a specified value in the specified range. + * If value less than the minimal value, + * the method returns the minimal value. + * If value greater than the maximal value, + * the method returns the maximal value. + * + * @param value the value to normalize + * @param min the minimal value of the range + * @param max the maximal value of the range + * @return a normalized value + */ + private static int normalize(int value, int min, int max) { + return value < min ? min : value > max ? max : value; + } + + /** + * Returns a square of the distance from + * the specified point to the specified rectangle, + * which does not contain the specified point. + * + * @param x the X coordinate of the specified point + * @param y the Y coordinate of the specified point + * @return a square of the distance + */ + private static int distance(Rectangle bounds, int x, int y) { + x -= normalize(x, bounds.x, bounds.x + bounds.width); + y -= normalize(y, bounds.y, bounds.y + bounds.height); + return x * x + y * y; } public static boolean isOutsideOnTheRightOFScreen(Rectangle rect) { |