
net.vectorpublish.desktop.vp.pd.official.DrawPanel Maven / Gradle / Ivy
/*
* Copyright (c) 2016, Peter Rader. All rights reserved.
* ___ ___ __ ______ __ __ __ __
* | | |.-----..----.| |_ .-----..----.| __ \.--.--.| |--.| ||__|.-----.| |--.
* | | || -__|| __|| _|| _ || _|| __/| | || _ || || ||__ --|| |
* \_____/ |_____||____||____||_____||__| |___| |_____||_____||__||__||_____||__|__|
*
* http://www.gnu.org/licenses/gpl-3.0.html
*/
package net.vectorpublish.desktop.vp.pd.official;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.FocusEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.util.Objects;
import javax.swing.AbstractAction;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.UIManager;
import net.vectorpublish.desktop.vp.api.io.DrawArea;
import net.vectorpublish.desktop.vp.api.ui.KeyframeSlider;
import net.vectorpublish.desktop.vp.system.LayoutAdapter;
public class DrawPanel extends JPanel implements ItemListener, AdjustmentListener {
private final DrawArea drawArea;
private String title;
private final JScrollBar vert = new JScrollBar(JScrollBar.VERTICAL);
private final JScrollBar hor = new JScrollBar(JScrollBar.HORIZONTAL);
private final DefaultComboBoxModel zoomModel = new DefaultComboBoxModel<>();
private final JComboBox zoom = new JComboBox<>(zoomModel);
/**
* The distance in real pixel between the left point of the component and
* the document left border.
*/
int drawTargetX;
/**
* The distance in real pixel between the upper point of the component and
* the top border of the document.
*/
int drawTargetY;
ZoomPercent zoomPercent;
private final KeyframeSlider slider;
public DrawPanel(String title, DrawArea drawArea, KeyframeSlider slider) {
super();
this.slider = slider;
for (int percent = 10; percent < 200; percent += 10) {
zoomModel.addElement(percent);
}
for (int percent = 200; percent < 1000; percent += 100) {
zoomModel.addElement(percent);
}
for (int percent = 1000; percent < 10000; percent += 1000) {
zoomModel.addElement(percent);
}
zoom.setSelectedIndex(9);
this.title = title;
this.drawArea = Objects.requireNonNull(drawArea);
add(vert);
vert.addAdjustmentListener(this);
add(hor);
hor.addAdjustmentListener(this);
add(zoom);
zoom.addItemListener(this);
final MouseListenerImplementation l = new MouseListenerImplementation(this, slider);
addMouseMotionListener(l);
addMouseListener(l);
setFocusable(true);
final ActionBinding altDown = new ActionBinding(true, KeyEvent.VK_ALT, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent event) {
l.setAltDown(true);
}
});
altDown.bind(this);
final ActionBinding altUp = new ActionBinding(false, KeyEvent.VK_ALT, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent event) {
l.setAltDown(false);
}
});
altUp.bind(this);
final ActionBinding shiftDown = new ActionBinding(true, KeyEvent.VK_SHIFT, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent event) {
l.setShiftDown(true);
}
});
shiftDown.bind(this);
final ActionBinding shiftUp = new ActionBinding(false, KeyEvent.VK_SHIFT, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
l.setShiftDown(false);
}
});
shiftUp.bind(this);
final ActionBinding ctrlDown = new ActionBinding(true, KeyEvent.VK_CONTROL, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent event) {
l.setControlDown(true);
}
});
ctrlDown.bind(this);
final ActionBinding ctrlUp = new ActionBinding(false, KeyEvent.VK_CONTROL, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent event) {
l.setControlDown(false);
}
});
ctrlUp.bind(this);
setLayout(new LayoutAdapter() {
@Override
public void layoutContainer(Container parent) {
final int w = getWidth();
final int h = getHeight();
final int scrollBottomHeight = 20;
final int scrollRightWidth = 20;
final int zoomWidth = 70;
vert.setBounds(w - scrollRightWidth, 0, scrollRightWidth, h - scrollBottomHeight);
hor.setBounds(0, h - scrollBottomHeight, w - zoomWidth, scrollBottomHeight);
zoom.setBounds(w - zoomWidth, h - scrollBottomHeight, zoomWidth, scrollBottomHeight);
final int percent = getZoomPercent().getPercent();
final Dimension pixelsize = drawArea.getDimensions();
final double drawWidth = (pixelsize.width) / 100d * percent;
final double drawHeight = (pixelsize.height) / 100d * percent;
final int viewportWidth = w - scrollRightWidth;
final int viewportHeight = h - scrollBottomHeight;
final boolean tooWide = viewportWidth < drawWidth;
final boolean tooHeight = viewportHeight < drawHeight;
vert.setEnabled(tooHeight);
hor.setEnabled(tooWide);
final int halfInvisiblePixelX;
if (tooWide) {
halfInvisiblePixelX = (int) (drawWidth - viewportWidth) / 2;
} else {
halfInvisiblePixelX = 0;
}
hor.setMinimum(0);
hor.setMaximum(halfInvisiblePixelX * 2);
final int halfInvisiblePixelY;
if (tooHeight) {
halfInvisiblePixelY = (int) (drawHeight - viewportHeight) / 2;
} else {
halfInvisiblePixelY = 0;
}
vert.setMinimum(0);
vert.setMaximum(halfInvisiblePixelY * 2);
if (tooWide) {
drawTargetX = -hor.getValue();
} else {
drawTargetX = (int) ((w - scrollRightWidth - drawWidth) / 2);
}
if (tooHeight) {
drawTargetY = -vert.getValue();
} else {
drawTargetY = (int) ((h - scrollBottomHeight - drawHeight) / 2);
}
}
});
}
@Override
public void adjustmentValueChanged(AdjustmentEvent event) {
doLayout();
repaint();
}
/**
* Returns the {@link DrawArea}.
*
* Returns always the same and never null
.
*
* @return The {@link DrawArea}, never null
.
*/
public DrawArea getDrawArea() {
return drawArea;
}
/**
* Returns the Title of the Document.
*
* @return The title, can be a Filename or (on non-saved documents) a
* auto-generated value.
*/
public String getTitle() {
return title;
}
/**
* Returns the current Zoom of the DrawPanel.
*
* @return the Zoom, never null
.
*/
public ZoomPercent getZoomPercent() {
if (zoomPercent == null) {
return ZoomPercent.DEFAULT;
}
return zoomPercent;
}
@Override
public void itemStateChanged(ItemEvent event) {
final int v = (int) zoom.getSelectedItem();
if (zoomPercent == null || zoomPercent.getPercent() != v) {
this.zoomPercent = new ZoomPercent(v);
}
doLayout();
repaint();
}
@Override
protected void paintComponent(Graphics graph) {
// paint page background
graph.setColor(Color.lightGray);
graph.fillRect(0, 0, getWidth(), getHeight());
final Dimension documentSize = drawArea.getDimensions();
final int layerType = drawArea.opacity() ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB;
final BufferedImage pixelImage = new BufferedImage(documentSize.width, documentSize.height, layerType);
final VectorPublishGraphics pixelGraphics = new VectorPublishGraphics(pixelImage);
if (layerType == BufferedImage.TYPE_INT_ARGB) {
pixelGraphics.setColor(new Color(0, 0, 0, 0));
pixelGraphics.fillRect(0, 0, documentSize.width, documentSize.height);
}
drawArea.paint(pixelGraphics, documentSize.width, documentSize.height);
final BufferedImage outer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
final VectorPublishGraphics outerGraphics = new VectorPublishGraphics(outer);
final RelativeKeyframeRecalculator recalculator = new RelativeKeyframeRecalculator(drawTargetX, drawTargetY, documentSize.width, documentSize.height, getZoomPercent(), slider.getTime(), this.drawArea.getDocument());
drawArea.paintOutside(outerGraphics, recalculator, documentSize.width, documentSize.height);
graph.setColor(Color.white);
final int scaledDocumentWidth = (int) (documentSize.getWidth() / 100f * getZoomPercent().getPercent());
final int scaledDocumentHeight = (int) (documentSize.getHeight() / 100f * getZoomPercent().getPercent());
paintCutLines(graph, scaledDocumentWidth, scaledDocumentHeight);
graph.drawImage(pixelImage, drawTargetX, drawTargetY, scaledDocumentWidth, scaledDocumentHeight, null);
graph.drawImage(outer, 0, 0, null);
if (hasFocus()) {
final Color color = (Color) UIManager.get("Button.focus");
graph.setColor(color);
graph.drawRect(1, 1, getWidth() - 2, getHeight() - 2);
}
}
public void paintCutLines(Graphics graph, final int scaledDocumentWidth, final int scaledDocumentHeight) {
graph.drawLine(drawTargetX - 20, drawTargetY, drawTargetX - 5, drawTargetY);
graph.drawLine(drawTargetX, drawTargetY - 20, drawTargetX, drawTargetY - 5);
graph.drawLine(drawTargetX - 20, drawTargetY + scaledDocumentHeight, drawTargetX - 5, drawTargetY + scaledDocumentHeight);
graph.drawLine(drawTargetX, drawTargetY + scaledDocumentHeight + 5, drawTargetX, drawTargetY + scaledDocumentHeight + 20);
graph.drawLine(drawTargetX + scaledDocumentWidth + 5, drawTargetY, drawTargetX + scaledDocumentWidth + 20, drawTargetY);
graph.drawLine(drawTargetX + scaledDocumentWidth + 5, drawTargetY + scaledDocumentHeight, drawTargetX + scaledDocumentWidth + 20, drawTargetY + scaledDocumentHeight);
graph.drawLine(drawTargetX + scaledDocumentWidth, drawTargetY - 20, drawTargetX + scaledDocumentWidth, drawTargetY - 5);
graph.drawLine(drawTargetX + scaledDocumentWidth, drawTargetY + scaledDocumentHeight + 5, drawTargetX + scaledDocumentWidth, drawTargetY + scaledDocumentHeight + 20);
}
@Override
protected void processFocusEvent(FocusEvent e) {
super.processFocusEvent(e);
repaint();
}
public void setTitle(String title) {
this.title = title;
}
}