diff --git a/images/src/org/intellij/images/editor/ImageZoomModel.java b/images/src/org/intellij/images/editor/ImageZoomModel.java index 8b7fb60f0a74..5612885361bb 100644 --- a/images/src/org/intellij/images/editor/ImageZoomModel.java +++ b/images/src/org/intellij/images/editor/ImageZoomModel.java @@ -22,8 +22,12 @@ package org.intellij.images.editor; * @author Alexey Efimov */ public interface ImageZoomModel { - int MACRO_ZOOM_LIMIT = 32; - int MICRO_ZOOM_LIMIT = 8; + int MACRO_ZOOM_POWER_LIMIT = 5; + int MICRO_ZOOM_POWER_LIMIT = 8; + double MACRO_ZOOM_RATIO = 2.0d; + double MICRO_ZOOM_RATIO = 1.5d; + double MACRO_ZOOM_LIMIT = Math.pow(MACRO_ZOOM_RATIO, MACRO_ZOOM_POWER_LIMIT); + double MICRO_ZOOM_LIMIT = Math.pow(1 / MICRO_ZOOM_RATIO, MICRO_ZOOM_POWER_LIMIT); double getZoomFactor(); diff --git a/images/src/org/intellij/images/editor/impl/ImageEditorUI.java b/images/src/org/intellij/images/editor/impl/ImageEditorUI.java index 9d613447597a..98b3c4cc0c7a 100644 --- a/images/src/org/intellij/images/editor/impl/ImageEditorUI.java +++ b/images/src/org/intellij/images/editor/impl/ImageEditorUI.java @@ -373,11 +373,11 @@ final class ImageEditorUI extends JPanel implements DataProvider, CopyProvider, private class ImageZoomModelImpl implements ImageZoomModel { private boolean myZoomLevelChanged; - private final NotNullValue MAX_ZOOM_FACTOR = new NotNullValue() { + private final NotNullValue IMAGE_MAX_ZOOM_FACTOR = new NotNullValue() { @NotNull @Override public Double initialize() { - if (editor == null) return (double)ImageZoomModel.MACRO_ZOOM_LIMIT; + if (editor == null) return Double.MAX_VALUE; VirtualFile file = editor.getFile(); if (IfsUtil.isSVG(file)) { @@ -389,7 +389,7 @@ final class ImageEditorUI extends JPanel implements DataProvider, CopyProvider, Logger.getInstance("#org.intellij.images.editor.impl.ImageEditorUI").warn(t); } } - return (double)ImageZoomModel.MACRO_ZOOM_LIMIT; + return Double.MAX_VALUE; } }; private double zoomFactor = 0.0d; @@ -414,9 +414,15 @@ final class ImageEditorUI extends JPanel implements DataProvider, CopyProvider, imageComponent.firePropertyChange(ZOOM_FACTOR_PROP, oldZoomFactor, zoomFactor); } + private double getMaximumZoomFactor() { + double factor = IMAGE_MAX_ZOOM_FACTOR.get(); + return Math.min(factor, MACRO_ZOOM_LIMIT); + } + private double getMinimumZoomFactor() { BufferedImage image = imageComponent.getDocument().getValue(); - return image != null ? 1.0d / image.getWidth() : 0.0d; + double factor = image != null ? 1.0d / image.getWidth() : 0.0d; + return Math.max(factor, MICRO_ZOOM_LIMIT); } public void fitZoomToWindow() { @@ -434,18 +440,7 @@ final class ImageEditorUI extends JPanel implements DataProvider, CopyProvider, } public void zoomOut() { - double factor = getZoomFactor(); - if (factor > 1.0d) { - // Macro - setZoomFactor(factor / 2.0d); - } else { - // Micro - double minFactor = getMinimumZoomFactor(); - double stepSize = (1.0d - minFactor) / MICRO_ZOOM_LIMIT; - int step = (int)Math.ceil((1.0d - factor) / stepSize); - - setZoomFactor(1.0d - stepSize * (step + 1)); - } + setZoomFactor(getNextZoomOut()); myZoomLevelChanged = true; } @@ -454,33 +449,41 @@ final class ImageEditorUI extends JPanel implements DataProvider, CopyProvider, myZoomLevelChanged = true; } + private double getNextZoomOut() { + double factor = getZoomFactor(); + if (factor > 1.0d) { + // Macro + factor /= MACRO_ZOOM_RATIO; + factor = Math.max(factor, 1.0d); + } + else { + // Micro + factor /= MICRO_ZOOM_RATIO; + } + return Math.max(factor, getMinimumZoomFactor()); + } + private double getNextZoomIn() { double factor = getZoomFactor(); if (factor >= 1.0d) { // Macro - factor *= 2.0d; - } else { - // Micro - double minFactor = getMinimumZoomFactor(); - double stepSize = (1.0d - minFactor) / MICRO_ZOOM_LIMIT; - double step = (1.0d - factor) / stepSize; - - factor = 1.0d - stepSize * (step - 1); + factor *= MACRO_ZOOM_RATIO; } - return Math.min(factor, MAX_ZOOM_FACTOR.get()); + else { + // Micro + factor *= MICRO_ZOOM_RATIO; + factor = Math.min(factor, 1.0d); + } + return Math.min(factor, getMaximumZoomFactor()); } public boolean canZoomOut() { - double factor = getZoomFactor(); - double minFactor = getMinimumZoomFactor(); - double stepSize = (1.0 - minFactor) / MICRO_ZOOM_LIMIT; - double step = Math.ceil((1.0 - factor) / stepSize); - - return step < MICRO_ZOOM_LIMIT; + // Ignore small differences caused by floating-point arithmetic. + return getZoomFactor() - 1.0e-14 > getMinimumZoomFactor(); } public boolean canZoomIn() { - return getZoomFactor() < MAX_ZOOM_FACTOR.get(); + return getZoomFactor() < getMaximumZoomFactor(); } @Override