net.vectorpublish.desktop.vp.split.Split Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2016, Peter Rader. All rights reserved.
* ___ ___ __ ______ __ __ __ __
* | | |.-----..----.| |_ .-----..----.| __ \.--.--.| |--.| ||__|.-----.| |--.
* | | || -__|| __|| _|| _ || _|| __/| | || _ || || ||__ --|| |
* \_____/ |_____||____||____||_____||__| |___| |_____||_____||__||__||_____||__|__|
*
* http://www.gnu.org/licenses/gpl-3.0.html
*/
package net.vectorpublish.desktop.vp.split;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.geom.Rectangle2D.Float;
import java.util.Objects;
import java.util.Set;
import net.vectorpublish.desktop.vp.api.DrawParticipant;
import net.vectorpublish.desktop.vp.api.Moment;
import net.vectorpublish.desktop.vp.api.layer.IllegalParentException;
import net.vectorpublish.desktop.vp.api.ui.kf.Keyframe;
import net.vectorpublish.desktop.vp.api.ui.kf.Keyframer;
import net.vectorpublish.desktop.vp.api.vpd.DocumentNode;
import net.vectorpublish.desktop.vp.api.vpd.ModificationContext.LayerNodeImpl;
import net.vectorpublish.desktop.vp.api.vpd.VectorPublishNode;
import net.vectorpublish.desktop.vp.pd.official.RelativeKeyframeRecalculator;
import net.vectorpublish.desktop.vp.pd.official.TechnicalMouseDrag;
import net.vectorpublish.desktop.vp.pd.official.VectorPublishGraphics;
public class Split implements Keyframer, Spliter {
private static final int PRECISION = 10_000;
private float percent;
private boolean vertical, selected;
private DocumentNode doc;
private int borderWidth2, borderWidth1;
public Split(DocumentNode doc, int border, float percent, boolean vertical) {
this.doc = Objects.requireNonNull(doc);
this.setBorderWidth(border);
this.percent = percent;
this.vertical = vertical;
}
public int getBorderWidth() {
return borderWidth1 + borderWidth2;
}
Float rect;
boolean drawHelpLines;
@Override
public Cursor updateMouse(int markerX, int markerY, float docRelX, float docRelY, RelativeKeyframeRecalculator rel,
TechnicalMouseDrag pressedLMBSince) {
Dimension outerSize = findSize();
Float relative = calulateChildRectangle(true);
Float sideT = rel.toTechnical(relative);
drawHelpLines = markerX > sideT.x && markerX < sideT.x + rel.calcTechnicalWidth(outerSize.width) && markerY > sideT.y
&& markerY < sideT.y + sideT.height;
int border1 = rel.calcTechnicalWidth(borderWidth1);
int border2 = rel.calcTechnicalWidth(borderWidth2);
if (border1 + border2 < 10) {
border1 = 5;
border2 = 5;
}
if (pressedLMBSince == null || !pressedLMBSince.hasHandler()) {
Float borderRect = sliderRect(sideT.x, sideT.y, sideT.width, sideT.height, border1, border2);
boolean mouseInBorder = borderRect.contains(markerX, markerY);
if (mouseInBorder) {
rect = borderRect;
if (pressedLMBSince != null) {
pressedLMBSince.setHandler(this);
}
}
return mouseInBorder ? Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR) : null;
}
if (pressedLMBSince != null && pressedLMBSince.isHandler(this)) {
if (vertical) {
percent = (markerX - sideT.x) / rel.calcTechnicalWidth(outerSize.width) * 100f;
if (percent < 0) {
percent = 0;
}
if (percent > 100) {
percent = 100;
}
} else {
percent = (markerY - sideT.y) / rel.calcTechnicalHeight(outerSize.height) * 100f;
if (percent < 0) {
percent = 0;
}
if (percent > 100) {
percent = 100;
}
rect = sliderRect(sideT.x, sideT.y, sideT.width, sideT.height, border1, border2);
}
}
return null;
}
private Dimension findSize() {
VectorPublishNode sp = findNodeHavingSpliterParent(this);
Dimension outerSize = sp == null ? doc.getParticipant().getDimensions()
: ((SplitNode) sp.getParent()).getParticipant().getDimensions();
return outerSize;
}
private Float sliderRect(float x, float y, float w, float h, int span1, int span2) {
Float sliderRect = null;
if (vertical) {
sliderRect = new Float(x + w, y, span1 + span2, h);
} else {
sliderRect = new Float(x - span1, y - span1 + h, w + 10, 10);
}
return sliderRect;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
public boolean isSelected() {
return selected;
}
@Override
public Dimension getDimensions() {
Float r = calculateRectangle();
return new Dimension((int) r.width, (int) r.height);
}
@Override
public boolean opacity() {
return false;
}
@Override
public void paint(VectorPublishGraphics graphics, int width, int height) {
doc.paintChildren(this, graphics, width, height);
}
@Override
public void paintOutside(VectorPublishGraphics graphics, RelativeKeyframeRecalculator r, int documentWidth,
int documentHeight) {
Float first = calulateChildRectangle(true);
Float second = calulateChildRectangle(false);
if (isSelected()) {
int xScale = r.calcTechnicalWidth(PRECISION);
int yScale = r.calcTechnicalHeight(PRECISION);
int x = (int) (r.calcTechnicalX(0) + xScale * first.x / PRECISION);
int y = (int) (r.calcTechnicalY(0) + yScale * first.y / PRECISION);
int w = (int) (xScale * first.width / PRECISION);
int h = (int) (yScale * first.height / PRECISION);
int x2 = (int) (r.calcTechnicalX(0) + xScale * second.x / PRECISION);
int y2 = (int) (r.calcTechnicalY(0) + yScale * second.y / PRECISION);
int w2 = (int) (xScale * second.width / PRECISION);
int h2 = (int) (yScale * second.height / PRECISION);
graphics.setColor(Color.blue);
Float mr = rect;
if (mr != null) {
graphics.fillRect((int) mr.x, (int) mr.y, (int) mr.width, (int) mr.height);
}
if (drawHelpLines) {
graphics.drawLine(x, y, x, y + 20);
}
}
doc.paintChildrenOuter(this, graphics, r, documentWidth, documentHeight);
}
@Override
public void reset(Set keyframes, Moment time) {
}
@Override
public Float calulateChildRectangle(boolean first) {
final Float self = calculateRectangle();
return halfOfBoundary(first, self);
}
private Float calculateRectangle() {
VectorPublishNode childOfParent = findNodeHavingSpliterParent(this);
final Float self;
if (childOfParent == null) {
Dimension dim = doc.getParticipant().getDimensions();
self = new Float(0f, 0f, dim.width * 1f, dim.height * 1f);
} else {
SplitNode parent = (SplitNode) childOfParent.getParent();
boolean isFirst = parent.getIndex(childOfParent) == 0;
self = parent.getParticipant().calulateChildRectangle(isFirst);
}
return self;
}
private Float halfOfBoundary(boolean first, Float self) {
if (first) {
if (vertical) {
return new Float(self.x, self.y, self.width / 100f * percent - borderWidth1, self.height);
} else {
return new Float(self.x, self.y, self.width, self.height / 100f * percent - borderWidth1);
}
} else {
if (vertical) {
float relX = self.width / 100f * percent;
return new Float(self.x + relX + borderWidth2, self.y, self.width - relX - borderWidth2, self.height);
} else {
float relY = self.height / 100f * percent;
return new Float(self.x, self.y + relY + borderWidth2, self.width, self.height - relY - borderWidth2);
}
}
}
private VectorPublishNode findNodeHavingSpliterParent(Split split) {
VectorPublishNode current = doc.findSelfOrChildByPaintParticipant(this);
while (current != null) {
if (current.getParent() instanceof SplitNode) {
return current;
}
current = current.getParent();
}
return null;
}
@Override
public String toString() {
return vertical ? "Left " + Math.round(percent * 10) / 10f : "Top " + Math.round(percent * 10) / 10f;
}
public void setBorderWidth(Integer border) {
if (border % 2 == 0) {
borderWidth1 = borderWidth2 = border / 2;
} else {
borderWidth1 = (int) Math.floor(border * 1d / 2);
borderWidth2 = (int) Math.ceil(border * 1d / 2);
}
}
/**
* Finds the bounds of the split
*
* @see #calulateChildRectangle(boolean)
* @param node
* The node we need the rectangle for, never null
.
* @return The rectangle the node is bound to, never null
.
* @throws IllegalParentException
* If the node is no the first or second child of a splitter.
*/
public static Float calculateRectangle(LayerNodeImpl node) throws IllegalParentException {
while (!(node.getParent() instanceof DocumentNode)) {
VectorPublishNode parent = node.getParent();
if (parent instanceof SplitNode) {
SplitNode splitParent = (SplitNode) parent;
int index = splitParent.getIndex(node);
if (index == 0) {
return splitParent.getParticipant().calulateChildRectangle(true);
} else if (index == 1) {
return splitParent.getParticipant().calulateChildRectangle(false);
} else {
throw new IllegalParentException(node, "Must be first child or second child of parent.");
}
}
}
Dimension dim = node.getDocumentNode().getParticipant().getDimensions();
return new Float(0, 0, dim.width, dim.height);
}
}