From b960d37a4a813cc5cf06bd1ddf399262756b90d3 Mon Sep 17 00:00:00 2001 From: Daniel_M_Williams Date: Sat, 8 Aug 2020 18:08:09 -0400 Subject: [PATCH] [fix] dragging fin points will now drag the view pane (preventing a user from dragging a point out of view) --- .../configdialog/FreeformFinSetConfig.java | 134 ++++++++++++++---- .../gui/scalefigure/AbstractScaleFigure.java | 5 +- .../gui/scalefigure/ScaleScrollPane.java | 4 +- .../gui/scalefigure/ScaleSelector.java | 8 +- 4 files changed, 119 insertions(+), 32 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java index cba48414c..d237bb962 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java @@ -1,8 +1,11 @@ package net.sf.openrocket.gui.configdialog; +import java.awt.Dimension; import java.awt.Point; +import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.ComponentEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.Point2D; @@ -32,6 +35,7 @@ import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.table.AbstractTableModel; +import net.sf.openrocket.util.MathUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -74,9 +78,10 @@ public class FreeformFinSetConfig extends FinSetConfig { private FinPointTableModel tableModel = null; private int dragIndex = -1; - + private Point dragPoint = null; + private FinPointFigure figure = null; - + private ScaleSelector selector; public FreeformFinSetConfig(OpenRocketDocument d, RocketComponent component) { super(d, component); @@ -226,11 +231,11 @@ public class FreeformFinSetConfig extends FinSetConfig { table.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent ev) { - figure.setSelectedIndex(table.getSelectedRow()); - figure.updateFigure(); - } + figure.setSelectedIndex(table.getSelectedRow()); + figure.updateFigure(); + } - }); + }); JScrollPane tablePane = new JScrollPane(table); JButton scaleButton = new JButton(trans.get("FreeformFinSetConfig.lbl.scaleFin")); @@ -270,7 +275,7 @@ public class FreeformFinSetConfig extends FinSetConfig { importImage(); } }); - ScaleSelector selector = new ScaleSelector(figurePane); + selector = new ScaleSelector(figurePane); // fit on first start-up figurePane.setFitting(true); @@ -390,58 +395,134 @@ public class FreeformFinSetConfig extends FinSetConfig { private class FinPointScrollPane extends ScaleScrollPane { private static final int ANY_MASK = (MouseEvent.ALT_DOWN_MASK | MouseEvent.ALT_GRAPH_DOWN_MASK | MouseEvent.META_DOWN_MASK | MouseEvent.CTRL_DOWN_MASK | MouseEvent.SHIFT_DOWN_MASK); - - - - private FinPointScrollPane( final FinPointFigure _figure) { - super( _figure); + + + private FinPointScrollPane(final FinPointFigure _figure) { + super(_figure); } - + @Override public void mousePressed(MouseEvent event) { int mods = event.getModifiersEx(); - - final FreeformFinSet finset = (FreeformFinSet)component; - + + final FreeformFinSet finset = (FreeformFinSet) component; + final int pressIndex = getPoint(event); - if ( pressIndex >= 0) { + if (pressIndex >= 0) { dragIndex = pressIndex; + dragPoint = event.getPoint(); + updateFields(); return; } - + final int segmentIndex = getSegment(event); if (segmentIndex >= 0) { Point2D.Double point = getCoordinates(event); finset.addPoint(segmentIndex, point); dragIndex = segmentIndex; + dragPoint = event.getPoint(); + updateFields(); return; } - + super.mousePressed(event); } - + @Override public void mouseDragged(MouseEvent event) { - int mods = event.getModifiersEx(); + int mods = event.getModifiersEx(); if (dragIndex < 0 || (mods & (ANY_MASK | MouseEvent.BUTTON1_DOWN_MASK)) != MouseEvent.BUTTON1_DOWN_MASK) { super.mouseDragged(event); return; } - - Point2D.Double point = getCoordinates(event); - final FreeformFinSet finset = (FreeformFinSet)component; + Point2D.Double point = getCoordinates(event); + final FreeformFinSet finset = (FreeformFinSet) component; finset.setPoint(dragIndex, point.x, point.y); - + + dragPoint.x = event.getX(); + dragPoint.y = event.getY(); + updateFields(); + + // if point is within borders of figure _AND_ outside borders of the ScrollPane's view: + final Rectangle dragRectangle = viewport.getViewRect(); + final Point canvasPoint = new Point( dragPoint.x + dragRectangle.x, dragPoint.y + dragRectangle.y); + if( (figure.getBorderWidth() < canvasPoint.x) && (canvasPoint.x < (figure.getWidth() - figure.getBorderWidth())) + && (figure.getBorderHeight() < canvasPoint.y) && (canvasPoint.y < (figure.getHeight() - figure.getBorderHeight()))) + { + boolean hitBorder = false; + if(dragPoint.x < figure.getBorderWidth()){ + hitBorder = true; + dragRectangle.x += dragPoint.x - figure.getBorderWidth(); + } else if(dragPoint.x >(dragRectangle.width -figure.getBorderWidth())) { + hitBorder = true; + dragRectangle.x += dragPoint.x - (dragRectangle.width - figure.getBorderWidth()); + } + + if (dragPoint.y(dragRectangle.height -figure.getBorderHeight())) { + hitBorder = true; + dragRectangle.y += dragPoint.y - (dragRectangle.height - figure.getBorderHeight()); + } + + if (hitBorder) { + super.setFitting(false); + selector.update(); + figure.scrollRectToVisible(dragRectangle); + revalidate(); + } + } } - + + @Override + public void componentResized(ComponentEvent e) { + if (fit) { + // if we're fitting the whole figure in the ScrollPane, the parent behavior is fine + super.componentResized(e); + } else if (0 > dragIndex) { + // if we're not _currently_ dragging a point, the parent behavior is fine + super.componentResized(e); + } else { + // currently dragging a point. + // ... and if we drag out-of-bounds, we want to move the viewport to keep up + boolean hitBorder = false; + final Rectangle dragRectangle = viewport.getViewRect(); + + if(dragPoint.x(dragRectangle.width -figure.getBorderWidth())) { + hitBorder = true; + dragRectangle.x += dragPoint.x - (dragRectangle.width - figure.getBorderWidth()); + } + + if (dragPoint.y(dragRectangle.height -figure.getBorderHeight())) { + hitBorder = true; + dragRectangle.y += dragPoint.y - (dragRectangle.height - figure.getBorderHeight()); + } + + if (hitBorder) { + super.setFitting(false); + selector.update(); + figure.scrollRectToVisible(dragRectangle); + revalidate(); + } + } + } + @Override public void mouseReleased(MouseEvent event) { dragIndex = -1; + dragPoint = null; super.mouseReleased(event); } @@ -453,7 +534,6 @@ public class FreeformFinSetConfig extends FinSetConfig { if ( 0 < clickIndex) { // if ctrl+click, delete point try { - Point2D.Double point = getCoordinates(event); final FreeformFinSet finset = (FreeformFinSet)component; finset.removePoint(clickIndex); } catch (IllegalFinPointException ignore) { diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/AbstractScaleFigure.java b/swing/src/net/sf/openrocket/gui/scalefigure/AbstractScaleFigure.java index 3c479d074..c29f30001 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/AbstractScaleFigure.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/AbstractScaleFigure.java @@ -76,7 +76,10 @@ public abstract class AbstractScaleFigure extends JPanel { setBackground(Color.WHITE); setOpaque(true); } - + + public int getBorderHeight(){ return borderThickness_px.height; } + public int getBorderWidth(){ return borderThickness_px.width; } + public double getUserScale(){ return userScale; } diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java b/swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java index 4e793e7f7..6431ebebd 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java @@ -60,11 +60,11 @@ public class ScaleScrollPane extends JScrollPane private Ruler verticalRuler; // is the subject *currently* being fitting - private boolean fit = false; + protected boolean fit = false; // magic number. I don't know why this number works, but this nudges the figures to zoom correctly. // n.b. it is slightly large than the ruler.width + scrollbar.width - final Dimension viewportMarginPx = new Dimension( 40, 40); + final protected Dimension viewportMarginPx = new Dimension( 40, 40); private Point2D.Double viewCenter_frac = new Point2D.Double(0.5f, 0.5f); diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/ScaleSelector.java b/swing/src/net/sf/openrocket/gui/scalefigure/ScaleSelector.java index a156a544c..5c49d3bee 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/ScaleSelector.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/ScaleSelector.java @@ -90,7 +90,7 @@ public class ScaleSelector extends JPanel { scrollPane.getFigure().addChangeListener(new StateChangeListener() { @Override public void stateChanged(EventObject e) { - setZoomText(); + update(); } }); add(scaleSelector, "gap rel"); @@ -103,7 +103,7 @@ public class ScaleSelector extends JPanel { double scale = scrollPane.getUserScale(); scale = getNextSmallerScale(scale); scrollPane.setScaling(scale); - setZoomText(); + update(); } }); add(button, "gapleft rel"); @@ -157,4 +157,8 @@ public class ScaleSelector extends JPanel { super.setEnabled(b); } + public void update(){ + setZoomText(); + } + }