allow extra space around the layout

introduced ability to render just the visible part of the layout for
better performance
This commit is contained in:
Branislav Stojkovic
2019-02-05 12:04:16 +01:00
parent ae3e698d9e
commit 3deb988a06
19 changed files with 198 additions and 65 deletions
@@ -235,7 +235,7 @@ public class TemplateDialog extends JDialog {
File file = (File) fileList.getSelectedValue();
if (file != null) {
presenter.loadProjectFromFile(file.getAbsolutePath());
Dimension dim = presenter.getCanvasDimensions(true);
Dimension dim = presenter.getCanvasDimensions(true, true);
double xFactor = panelSize.getWidth() / dim.getWidth();
double yFactor = panelSize.getHeight() / dim.getHeight();
presenter.setZoomLevel(Math.min(xFactor, yFactor));
@@ -67,7 +67,9 @@ public class CanvasPanel extends JComponent implements Autoscroll {
private static final long serialVersionUID = 1L;
private static final Logger LOG = Logger.getLogger(CanvasPlugin.class);
private static final Logger LOG = Logger.getLogger(CanvasPlugin.class);
public static boolean RENDER_VISIBLE_RECT_ONLY = true;
private IPlugInPort plugInPort;
@@ -208,12 +210,23 @@ public class CanvasPanel extends JComponent implements Autoscroll {
this.plugInPort.mouseMoved(getMousePosition(), false, false, false);
}
protected void createBufferImage() {
protected void createBufferImage() {
int imageWidth;
int imageHeight;
if (RENDER_VISIBLE_RECT_ONLY) {
Rectangle visibleRect = getVisibleRect();
imageWidth = visibleRect.width;
imageHeight = visibleRect.height;
} else {
imageWidth = getWidth();
imageHeight = getHeight();
}
if (useHardwareAcceleration) {
bufferImage = screenGraphicsConfiguration.createCompatibleVolatileImage(getWidth(), getHeight());
bufferImage = screenGraphicsConfiguration.createCompatibleVolatileImage(imageWidth, imageHeight);
((VolatileImage) bufferImage).validate(screenGraphicsConfiguration);
} else {
bufferImage = createImage(getWidth(), getHeight());
bufferImage = createImage(imageWidth, imageHeight);
}
}
@@ -225,8 +238,21 @@ public class CanvasPanel extends JComponent implements Autoscroll {
if (bufferImage == null) {
createBufferImage();
}
Graphics2D g2d = (Graphics2D) bufferImage.getGraphics();
g2d.setClip(getVisibleRect());
Graphics2D g2d = (Graphics2D) bufferImage.getGraphics();
Rectangle visibleRect = getVisibleRect();
int x = 0;
int y = 0;
if (RENDER_VISIBLE_RECT_ONLY) {
x = visibleRect.x;
y = visibleRect.y;
g2d.translate(-x, -y);
} else {
g2d.setClip(visibleRect);
}
Set<DrawOption> drawOptions = EnumSet.of(DrawOption.SELECTION, DrawOption.ZOOM, DrawOption.CONTROL_POINTS);
if (ConfigurationManager.getInstance().readBoolean(IPlugInPort.ANTI_ALIASING_KEY, true)) {
drawOptions.add(DrawOption.ANTIALIASING);
@@ -236,8 +262,13 @@ public class CanvasPanel extends JComponent implements Autoscroll {
}
if (ConfigurationManager.getInstance().readBoolean(IPlugInPort.SHOW_GRID_KEY, true)) {
drawOptions.add(DrawOption.GRID);
}
if (ConfigurationManager.getInstance().readBoolean(IPlugInPort.EXTRA_SPACE_KEY, true)) {
drawOptions.add(DrawOption.EXTRA_SPACE);
}
plugInPort.draw(g2d, drawOptions, null, null);
plugInPort.draw(g2d, drawOptions, null, null);
if (useHardwareAcceleration) {
VolatileImage volatileImage = (VolatileImage) bufferImage;
do {
@@ -250,13 +281,13 @@ public class CanvasPanel extends JComponent implements Autoscroll {
// if (validation == VolatileImage.IMAGE_INCOMPATIBLE) {
// createBufferImage();
// }
g.drawImage(bufferImage, 0, 0, this);
g.drawImage(bufferImage, x, y, this);
} catch (NullPointerException e) {
createBufferImage();
}
} while (volatileImage == null || volatileImage.contentsLost());
} else {
g.drawImage(bufferImage, 0, 0, this);
g.drawImage(bufferImage, x, y, this);
// bufferImage.flush();
}
g2d.dispose();
@@ -26,6 +26,8 @@ import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
@@ -106,7 +108,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
private Clipboard clipboard;
private double zoomLevel = 1;
public CanvasPlugin(ISwingUI swingUI) {
@@ -125,6 +127,27 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
getScrollPane().setRulerVisible(ConfigurationManager.getInstance().readBoolean(IPlugInPort.SHOW_RULERS_KEY, true));
// revalidate canvas on scrolling when we render visible rect only
if (CanvasPanel.RENDER_VISIBLE_RECT_ONLY) {
getScrollPane().getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
getCanvasPanel().invalidateCache();
getCanvasPanel().revalidate();
}
});
getScrollPane().getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
getCanvasPanel().invalidateCache();
getCanvasPanel().revalidate();
}
});
}
ConfigurationManager.getInstance().addConfigListener(IPlugInPort.SHOW_RULERS_KEY, new IConfigListener() {
@Override
@@ -133,30 +156,44 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
getScrollPane().setRulerVisible((Boolean) value);
}
});
ConfigurationManager.getInstance().addConfigListener(IPlugInPort.HARDWARE_ACCELERATION, new IConfigListener() {
@Override
public void valueChanged(String key, Object value) {
canvasPanel.setUseHardwareAcceleration((Boolean) value);
scrollPane.setUseHardwareAcceleration((Boolean) value);
}
});
ConfigurationManager.getInstance().addConfigListener(IPlugInPort.EXTRA_SPACE_KEY, new IConfigListener() {
@Override
public void valueChanged(String key, Object value) {
refreshSize();
// Scroll to the center.
Rectangle visibleRect = canvasPanel.getVisibleRect();
visibleRect.setLocation((canvasPanel.getWidth() - visibleRect.width) / 2,
(canvasPanel.getHeight() - visibleRect.height) / 2);
canvasPanel.scrollRectToVisible(visibleRect);
canvasPanel.revalidate();
}
});
}
public CanvasPanel getCanvasPanel() {
if (canvasPanel == null) {
canvasPanel = new CanvasPanel(plugInPort);
canvasPanel.addMouseListener(new MouseAdapter() {
private MouseEvent pressedEvent;
@Override
public void mouseClicked(MouseEvent e) {
if (scrollPane.isMouseScrollMode() || e.getButton() == MouseEvent.BUTTON2)
return;
plugInPort.mouseClicked(e.getPoint(), e.getButton(), Utils.isMac() ? e.isMetaDown() : e.isControlDown(), e.isShiftDown(), e.isAltDown(),
e.getClickCount());
plugInPort.mouseClicked(e.getPoint(), e.getButton(), Utils.isMac() ? e.isMetaDown() : e.isControlDown(),
e.isShiftDown(), e.isAltDown(), e.getClickCount());
}
@Override
@@ -174,7 +211,8 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
@Override
public void run() {
if (plugInPort.getNewComponentTypeSlot() == null && (e.isPopupTrigger() || (pressedEvent != null && pressedEvent.isPopupTrigger()))) {
if (plugInPort.getNewComponentTypeSlot() == null
&& (e.isPopupTrigger() || (pressedEvent != null && pressedEvent.isPopupTrigger()))) {
// Enable actions.
boolean enabled = !plugInPort.getSelectedComponents().isEmpty();
getCutAction().setEnabled(enabled);
@@ -214,7 +252,8 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
@Override
public void keyPressed(KeyEvent e) {
if (plugInPort.keyPressed(e.getKeyCode(), Utils.isMac() ? e.isMetaDown() : e.isControlDown(), e.isShiftDown(), e.isAltDown())) {
if (plugInPort.keyPressed(e.getKeyCode(), Utils.isMac() ? e.isMetaDown() : e.isControlDown(),
e.isShiftDown(), e.isAltDown())) {
e.consume();
}
}
@@ -227,7 +266,8 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
if (scrollPane.isMouseScrollMode())
return;
canvasPanel.setCursor(plugInPort.getCursorAt(e.getPoint()));
plugInPort.mouseMoved(e.getPoint(), Utils.isMac() ? e.isMetaDown() : e.isControlDown(), e.isShiftDown(), e.isAltDown());
plugInPort.mouseMoved(e.getPoint(), Utils.isMac() ? e.isMetaDown() : e.isControlDown(), e.isShiftDown(),
e.isAltDown());
}
});
}
@@ -237,11 +277,12 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
private RulerScrollPane getScrollPane() {
if (scrollPane == null) {
scrollPane =
new RulerScrollPane(getCanvasPanel(), new ProjectDrawingProvider(plugInPort, true, false), new Size(1d,
new RulerScrollPane(getCanvasPanel(), new ProjectDrawingProvider(plugInPort, true, false, true), new Size(1d,
SizeUnit.cm).convertToPixels(), new Size(1d, SizeUnit.in).convertToPixels());
boolean metric = ConfigurationManager.getInstance().readBoolean(Presenter.METRIC_KEY, true);
boolean useHardwareAcceleration = ConfigurationManager.getInstance().readBoolean(IPlugInPort.HARDWARE_ACCELERATION, false);
boolean useHardwareAcceleration =
ConfigurationManager.getInstance().readBoolean(IPlugInPort.HARDWARE_ACCELERATION, false);
scrollPane.setUseHardwareAcceleration(useHardwareAcceleration);
scrollPane.setMetric(metric);
@@ -655,7 +696,9 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
}
private void refreshSize() {
Dimension d = plugInPort.getCanvasDimensions(true);
Dimension d =
plugInPort.getCanvasDimensions(true,
ConfigurationManager.getInstance().readBoolean(IPlugInPort.EXTRA_SPACE_KEY, true));
canvasPanel.setSize(d);
canvasPanel.setPreferredSize(d);
getScrollPane().setZoomLevel(plugInPort.getZoomLevel());
@@ -216,7 +216,7 @@ public class UploadDialog extends ButtonDialog {
}
private Dimension getThumbnailSize() {
Dimension d = UploadDialog.this.plugInPort.getCanvasDimensions(false);
Dimension d = UploadDialog.this.plugInPort.getCanvasDimensions(false, false);
if (d.height > d.width)
return new Dimension(192 * d.width / d.height, 192);
else
@@ -304,7 +304,7 @@ public class UploadDialog extends ButtonDialog {
private void paintThumbnail(Graphics g, Rectangle rect) {
Graphics2D g2d = (Graphics2D) g;
Dimension d = UploadDialog.this.plugInPort.getCanvasDimensions(false);
Dimension d = UploadDialog.this.plugInPort.getCanvasDimensions(false, false);
g2d.setColor(Color.white);
g2d.fill(rect);
@@ -75,6 +75,9 @@ public class ConfigPlugin implements IPlugIn {
swingUI.injectMenuAction(
ActionFactory.getInstance().createConfigAction(plugInPort, "Export Grid", IPlugInPort.EXPORT_GRID_KEY, false),
CONFIG_MENU);
swingUI.injectMenuAction(
ActionFactory.getInstance().createConfigAction(plugInPort, "Extra Working Area", IPlugInPort.EXTRA_SPACE_KEY, true),
CONFIG_MENU);
swingUI.injectMenuAction(
ActionFactory.getInstance().createConfigAction(plugInPort, "Hardware Acceleration", IPlugInPort.HARDWARE_ACCELERATION, false),
CONFIG_MENU);
@@ -62,7 +62,7 @@ public class FileMenuPlugin implements IPlugIn, IDynamicSubmenuHandler {
@Override
public void connect(IPlugInPort plugInPort) {
this.plugInPort = plugInPort;
this.drawingProvider = new ProjectDrawingProvider(plugInPort, false, true);
this.drawingProvider = new ProjectDrawingProvider(plugInPort, false, true, false);
this.traceMaskDrawingProvider = new TraceMaskDrawingProvider(plugInPort);
ActionFactory actionFactory = ActionFactory.getInstance();
@@ -41,18 +41,20 @@ public class ProjectDrawingProvider implements IDrawingProvider {
private IPlugInPort plugInPort;
private boolean useZoom;
private boolean showGridWhenNeeded;
private boolean showGridWhenNeeded;
private boolean includeExtraSpace;
public ProjectDrawingProvider(IPlugInPort plugInPort, boolean useZoom, boolean showGridWhenNeeded) {
public ProjectDrawingProvider(IPlugInPort plugInPort, boolean useZoom, boolean showGridWhenNeeded, boolean includeExtraSpace) {
super();
this.plugInPort = plugInPort;
this.useZoom = useZoom;
this.showGridWhenNeeded = showGridWhenNeeded;
this.showGridWhenNeeded = showGridWhenNeeded;
this.includeExtraSpace = includeExtraSpace;
}
@Override
public Dimension getSize() {
return plugInPort.getCanvasDimensions(useZoom);
return plugInPort.getCanvasDimensions(useZoom, includeExtraSpace);
}
@Override
@@ -66,6 +68,9 @@ public class ProjectDrawingProvider implements IDrawingProvider {
}
if (ConfigurationManager.getInstance().readBoolean(IPlugInPort.OUTLINE_KEY, false)) {
drawOptions.add(DrawOption.OUTLINE_MODE);
}
if (includeExtraSpace) {
drawOptions.add(DrawOption.EXTRA_SPACE);
}
plugInPort.draw((Graphics2D) g, drawOptions, null, zoomFactor);
}
@@ -127,7 +127,7 @@ public class ProjectPreview extends JPanel implements PropertyChangeListener, IF
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
Dimension d = presenter.getCanvasDimensions(false);
Dimension d = presenter.getCanvasDimensions(false, false);
// System.out.println(d);
Rectangle rect = getBounds();
// System.out.println(rect);
@@ -55,7 +55,7 @@ public class TraceMaskDrawingProvider implements IDrawingProvider {
@Override
public Dimension getSize() {
return plugInPort.getCanvasDimensions(false);
return plugInPort.getCanvasDimensions(false, false);
}
@Override