mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Add zoom support to the designer infrastructure [fix-29696]
This commit is contained in:
+40
@@ -280,6 +280,26 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider
|
||||
public void showError(@NonNls String message, Throwable e) {
|
||||
DesignerEditorPanel.this.showError(message, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isZoomSupported() {
|
||||
return DesignerEditorPanel.this.isZoomSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void zoom(@NotNull ZoomType type) {
|
||||
DesignerEditorPanel.this.zoom(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setZoom(double zoom) {
|
||||
DesignerEditorPanel.this.setZoom(zoom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getZoom() {
|
||||
return DesignerEditorPanel.this.getZoom();
|
||||
}
|
||||
};
|
||||
|
||||
myGlassLayer = new GlassLayer(myToolProvider, mySurfaceArea);
|
||||
@@ -835,6 +855,26 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider
|
||||
return null;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zoom
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public boolean isZoomSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void zoom(@NotNull ZoomType type) {
|
||||
}
|
||||
|
||||
public void setZoom(double zoom) {
|
||||
}
|
||||
|
||||
public double getZoom() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Inspection
|
||||
|
||||
@@ -23,8 +23,8 @@ import java.awt.image.BufferedImage;
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public class RootView extends JComponent {
|
||||
private final int myX;
|
||||
private final int myY;
|
||||
protected final int myX;
|
||||
protected final int myY;
|
||||
protected BufferedImage myImage;
|
||||
|
||||
public RootView(int x, int y, BufferedImage image) {
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.designer.designSurface;
|
||||
|
||||
/**
|
||||
* Interface implemented by a design view native component which implements zooming.
|
||||
*/
|
||||
public interface ScalableComponent {
|
||||
/**
|
||||
* Returns the scale to apply to coordinates in this view.
|
||||
*/
|
||||
double getScale();
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.designer.designSurface;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface ZoomProvider {
|
||||
/**
|
||||
* Returns true if zooming is supported by this designer.
|
||||
*/
|
||||
boolean isZoomSupported();
|
||||
|
||||
/**
|
||||
* Zoom the editable area.
|
||||
*/
|
||||
void zoom(@NotNull ZoomType type);
|
||||
|
||||
/**
|
||||
* Sets the zoom level. Note that this should be 1, not 100 (percent), for an image at its actual size.
|
||||
*/
|
||||
void setZoom(double zoom);
|
||||
|
||||
/**
|
||||
* Returns the current zoom level. Note that this is 1, not 100 (percent) for an image at its actual size.
|
||||
*/
|
||||
double getZoom();
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.designer.designSurface;
|
||||
|
||||
public enum ZoomType {
|
||||
/**
|
||||
* Zoom in
|
||||
*/
|
||||
IN,
|
||||
|
||||
/**
|
||||
* Zoom out
|
||||
*/
|
||||
OUT,
|
||||
|
||||
/**
|
||||
* Zoom to actual size (100%)
|
||||
*/
|
||||
ACTUAL,
|
||||
|
||||
/**
|
||||
* Zoom to fit (the screen view port)
|
||||
*/
|
||||
FIT,
|
||||
|
||||
/**
|
||||
* Zoom to fit, but do not zoom more than 100%
|
||||
*/
|
||||
FIT_INTO,
|
||||
|
||||
/**
|
||||
* Zoom to match the exact device size (depends on the monitor dpi)
|
||||
*/
|
||||
SCREEN
|
||||
}
|
||||
+34
-4
@@ -16,6 +16,7 @@
|
||||
package com.intellij.designer.designSurface.tools;
|
||||
|
||||
import com.intellij.designer.designSurface.EditableArea;
|
||||
import com.intellij.designer.designSurface.ZoomType;
|
||||
import com.intellij.designer.model.RadComponent;
|
||||
import com.intellij.designer.propertyTable.InplaceContext;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
@@ -221,10 +222,39 @@ public class SelectionTool extends InputTool {
|
||||
if (myTracker != null) {
|
||||
myTracker.keyTyped(event, area);
|
||||
}
|
||||
else if (myToolProvider != null && !area.isTree() &&
|
||||
Character.isLetterOrDigit(event.getKeyChar()) &&
|
||||
(event.getModifiers() & (InputEvent.ALT_MASK | InputEvent.CTRL_MASK | InputEvent.META_MASK)) == 0) {
|
||||
myToolProvider.startInplaceEditing(new InplaceContext(event.getKeyChar()));
|
||||
else if (myToolProvider != null && !area.isTree()) {
|
||||
char keyChar = event.getKeyChar();
|
||||
switch (keyChar) {
|
||||
// Zoom
|
||||
case '-':
|
||||
case '+':
|
||||
case '0':
|
||||
case '1':
|
||||
ZoomType type;
|
||||
if (keyChar == '-') {
|
||||
type = ZoomType.OUT;
|
||||
}
|
||||
else if (keyChar == '+') {
|
||||
type = ZoomType.IN;
|
||||
}
|
||||
else if (keyChar == '0') {
|
||||
type = ZoomType.FIT;
|
||||
}
|
||||
else { // '1'
|
||||
type = ZoomType.ACTUAL;
|
||||
}
|
||||
if (myToolProvider.isZoomSupported()) {
|
||||
myToolProvider.zoom(type);
|
||||
event.consume();
|
||||
return;
|
||||
}
|
||||
// else: fall through
|
||||
default:
|
||||
if (Character.isLetterOrDigit(keyChar) &&
|
||||
(event.getModifiers() & (InputEvent.ALT_MASK | InputEvent.CTRL_MASK | InputEvent.META_MASK)) == 0) {
|
||||
myToolProvider.startInplaceEditing(new InplaceContext(keyChar));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -17,6 +17,7 @@ package com.intellij.designer.designSurface.tools;
|
||||
|
||||
import com.intellij.designer.designSurface.EditOperation;
|
||||
import com.intellij.designer.designSurface.EditableArea;
|
||||
import com.intellij.designer.designSurface.ZoomProvider;
|
||||
import com.intellij.designer.propertyTable.InplaceContext;
|
||||
import com.intellij.util.ThrowableRunnable;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -29,7 +30,7 @@ import java.util.List;
|
||||
/**
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public abstract class ToolProvider {
|
||||
public abstract class ToolProvider implements ZoomProvider {
|
||||
private InputTool myTool;
|
||||
private EditableArea myArea;
|
||||
private MouseEvent myEvent;
|
||||
|
||||
@@ -147,14 +147,139 @@ public abstract class RadComponent extends PropertiesContainer {
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Returns the bounds of this {@linkplain RadComponent} in the model.
|
||||
* <p/>
|
||||
* Caller should <b>not</b> modify this rectangle.
|
||||
*
|
||||
* @return the bounds of this {@linkplain RadComponent} in the model coordinate system
|
||||
* (e.g. unaffected by a view zoom for example)
|
||||
*/
|
||||
public Rectangle getBounds() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounds of this {@linkplain RadComponent} in the coordinate system of
|
||||
* the given Swing component. This will scale the coordinates if the view is zoomed
|
||||
* (see {@link DesignerEditorPanel#zoom(com.intellij.designer.designSurface.ZoomType)})
|
||||
* and will apply any relative position offsets of views in the hierarchy between the
|
||||
* two components.
|
||||
* <p/>
|
||||
* Returns a new {@link Rectangle}, so callers are free to modify the result.
|
||||
*
|
||||
* @param relativeTo the component whose coordinate system the model bounds should
|
||||
* be shifted and scaled into
|
||||
* @return the bounds of this {@linkplain RadComponent} in the given coordinate system
|
||||
*/
|
||||
public Rectangle getBounds(Component relativeTo) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given rectangle (in model coordinates) to coordinates in the given
|
||||
* target component's coordinate system. The model coordinate system refers to
|
||||
* the same coordinate system as the bounds returned by {@link #getBounds()}.
|
||||
* <p/>
|
||||
* This means that calling {@link #getBounds(java.awt.Component)} is equivalent
|
||||
* to calling this method and passing in {@link #getBounds()}.
|
||||
* <p/>
|
||||
* Returns a new {@link Rectangle}, so callers are free to modify the result.
|
||||
*
|
||||
* @param target the component whose coordinate system the rectangle should be
|
||||
* translated into
|
||||
* @param rectangle the model rectangle to convert
|
||||
* @return the rectangle converted to the coordinate system of the target
|
||||
*/
|
||||
public Rectangle fromModel(@NotNull Component target, @NotNull Rectangle rectangle) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given rectangle (in coordinates relative to the given component)
|
||||
* into the equivalent rectangle in model coordinates.
|
||||
* <p/>
|
||||
* Returns a new {@link Rectangle}, so callers are free to modify the result.
|
||||
*
|
||||
* @param source the component which defines the coordinate system of the rectangle
|
||||
* @param rectangle the rectangle to be converted into model coordinates
|
||||
* @return the rectangle converted to the model coordinate system
|
||||
*/
|
||||
public Rectangle toModel(@NotNull Component source, @NotNull Rectangle rectangle) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given point (in model coordinates) to coordinates in the given
|
||||
* target component's coordinate system. The model coordinate system refers to
|
||||
* the same coordinate system as the bounds returned by {@link #getBounds()}.
|
||||
* <p/>
|
||||
* Returns a new {@link Point}, so callers are free to modify the result.
|
||||
*
|
||||
* @param target the component whose coordinate system the point should be
|
||||
* translated into
|
||||
* @param point the model point to convert
|
||||
* @return the point converted to the coordinate system of the target
|
||||
*/
|
||||
public Point fromModel(@NotNull Component target, @NotNull Point point) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given point (in coordinates relative to the given component)
|
||||
* into the equivalent point in model coordinates.
|
||||
* <p/>
|
||||
* Returns a new {@link Point}, so callers are free to modify the result.
|
||||
*
|
||||
* @param source the component which defines the coordinate system of the point
|
||||
* @param point the point to be converted into model coordinates
|
||||
* @return the point converted to the model coordinate system
|
||||
*/
|
||||
public Point toModel(@NotNull Component source, @NotNull Point point) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given rectangle (in model coordinates) to coordinates in the given
|
||||
* target component's coordinate system. The model coordinate system refers to
|
||||
* the same coordinate system as the bounds returned by {@link #getBounds()}.
|
||||
* <p/>
|
||||
* Returns a new {@link Dimension}, so callers are free to modify the result.
|
||||
*
|
||||
* @param target the component whose coordinate system the dimension should be
|
||||
* translated into
|
||||
* @param size the model dimension to convert
|
||||
* @return the size converted to the coordinate system of the target
|
||||
*/
|
||||
public Dimension fromModel(@NotNull Component target, @NotNull Dimension size) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given size (in coordinates relative to the given component)
|
||||
* into the equivalent size in model coordinates.
|
||||
* <p/>
|
||||
* Returns a new {@link Dimension}, so callers are free to modify the result.
|
||||
*
|
||||
* @param source the component which defines the coordinate system of the size
|
||||
* @param size the dimension to be converted into model coordinates
|
||||
* @return the size converted to the model coordinate system
|
||||
*/
|
||||
public Dimension toModel(@NotNull Component source, @NotNull Dimension size) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the point in the model coordinate space (see {@link #getBounds()}) given
|
||||
* a coordinate {@code x, y} in the given Swing component.
|
||||
* <p/>
|
||||
* Returns a new {@link Point}, so callers are free to modify the result.
|
||||
*
|
||||
* @param relativeFrom the component whose coordinate system defines the rectangle
|
||||
* @param x the x coordinate of the point
|
||||
* @param y the y coordinate of the point
|
||||
* @return a corresponding {@link Point} in the model coordinate system
|
||||
*/
|
||||
public Point convertPoint(Component relativeFrom, int x, int y) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package com.intellij.designer.model;
|
||||
|
||||
import com.intellij.designer.designSurface.ScalableComponent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
@@ -32,9 +35,119 @@ public abstract class RadVisualComponent extends RadComponent {
|
||||
|
||||
@Override
|
||||
public Rectangle getBounds(Component relativeTo) {
|
||||
return myNativeComponent == relativeTo
|
||||
? new Rectangle(getBounds()) :
|
||||
SwingUtilities.convertRectangle(myNativeComponent, getBounds(), relativeTo);
|
||||
return fromModel(relativeTo, getBounds());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle fromModel(@NotNull Component target, @NotNull Rectangle bounds) {
|
||||
if (target != myNativeComponent && myNativeComponent instanceof ScalableComponent) {
|
||||
ScalableComponent scalableComponent = (ScalableComponent)myNativeComponent;
|
||||
double zoom = scalableComponent.getScale();
|
||||
|
||||
if (zoom != 1) {
|
||||
bounds = new Rectangle(bounds);
|
||||
bounds.x *= zoom;
|
||||
bounds.y *= zoom;
|
||||
bounds.width *= zoom;
|
||||
bounds.height *= zoom;
|
||||
}
|
||||
}
|
||||
|
||||
return myNativeComponent == target
|
||||
? new Rectangle(bounds) :
|
||||
SwingUtilities.convertRectangle(myNativeComponent, bounds, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle toModel(@NotNull Component source, @NotNull Rectangle rectangle) {
|
||||
Rectangle bounds = myNativeComponent == source
|
||||
? new Rectangle(rectangle) : SwingUtilities.convertRectangle(source, rectangle, myNativeComponent);
|
||||
|
||||
if (myNativeComponent != source && myNativeComponent instanceof ScalableComponent) {
|
||||
ScalableComponent scalableComponent = (ScalableComponent)myNativeComponent;
|
||||
double zoom = scalableComponent.getScale();
|
||||
|
||||
if (zoom != 1) {
|
||||
bounds = new Rectangle(bounds);
|
||||
bounds.x /= zoom;
|
||||
bounds.y /= zoom;
|
||||
bounds.width /= zoom;
|
||||
bounds.height /= zoom;
|
||||
}
|
||||
}
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point fromModel(@NotNull Component target, @NotNull Point point) {
|
||||
if (target != myNativeComponent && myNativeComponent instanceof ScalableComponent) {
|
||||
ScalableComponent scalableComponent = (ScalableComponent)myNativeComponent;
|
||||
double zoom = scalableComponent.getScale();
|
||||
|
||||
if (zoom != 1) {
|
||||
point = new Point(point);
|
||||
point.x *= zoom;
|
||||
point.y *= zoom;
|
||||
}
|
||||
}
|
||||
|
||||
return myNativeComponent == target
|
||||
? new Point(point) :
|
||||
SwingUtilities.convertPoint(myNativeComponent, point, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point toModel(@NotNull Component source, @NotNull Point point) {
|
||||
Point p = myNativeComponent == source
|
||||
? new Point(point) : SwingUtilities.convertPoint(source, point, myNativeComponent);
|
||||
|
||||
if (myNativeComponent != source && myNativeComponent instanceof ScalableComponent) {
|
||||
ScalableComponent scalableComponent = (ScalableComponent)myNativeComponent;
|
||||
double zoom = scalableComponent.getScale();
|
||||
|
||||
if (zoom != 1) {
|
||||
p = new Point(p);
|
||||
p.x /= zoom;
|
||||
p.y /= zoom;
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension fromModel(@NotNull Component target, @NotNull Dimension size) {
|
||||
size = new Dimension(size);
|
||||
|
||||
if (target != myNativeComponent && myNativeComponent instanceof ScalableComponent) {
|
||||
ScalableComponent scalableComponent = (ScalableComponent)myNativeComponent;
|
||||
double zoom = scalableComponent.getScale();
|
||||
|
||||
if (zoom != 1) {
|
||||
size.width *= zoom;
|
||||
size.height *= zoom;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension toModel(@NotNull Component source, @NotNull Dimension size) {
|
||||
size = new Dimension(size);
|
||||
|
||||
if (myNativeComponent != source && myNativeComponent instanceof ScalableComponent) {
|
||||
ScalableComponent scalableComponent = (ScalableComponent)myNativeComponent;
|
||||
double zoom = scalableComponent.getScale();
|
||||
|
||||
if (zoom != 1) {
|
||||
size.width /= zoom;
|
||||
size.height /= zoom;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setBounds(int x, int y, int width, int height) {
|
||||
@@ -43,9 +156,19 @@ public abstract class RadVisualComponent extends RadComponent {
|
||||
|
||||
@Override
|
||||
public Point convertPoint(Component relativeFrom, int x, int y) {
|
||||
return myNativeComponent == relativeFrom
|
||||
? new Point(x, y) :
|
||||
SwingUtilities.convertPoint(relativeFrom, x, y, myNativeComponent);
|
||||
Point p = myNativeComponent == relativeFrom ? new Point(x, y) : SwingUtilities.convertPoint(relativeFrom, x, y, myNativeComponent);
|
||||
|
||||
if (myNativeComponent != relativeFrom && myNativeComponent instanceof ScalableComponent) {
|
||||
ScalableComponent scalableComponent = (ScalableComponent)myNativeComponent;
|
||||
double zoom = scalableComponent.getScale();
|
||||
|
||||
if (zoom != 1) {
|
||||
p.x /= zoom;
|
||||
p.y /= zoom;
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
public Component getNativeComponent() {
|
||||
|
||||
Reference in New Issue
Block a user