tmpkus / piccolo2d

Automatically exported from code.google.com/p/piccolo2d
0 stars 0 forks source link

Support non-rectangular zooming of PCameras on nodes #16

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
The current methods on PCamera only allow zooming onto nodes with a
constrained scale.  This enhancement is to add a true fit-to-window scale
option.

Here is the proposed fix:
Index: src/edu/umd/cs/piccolo/PCamera.java
===================================================================
--- src/edu/umd/cs/piccolo/PCamera.java (revision 10)
+++ src/edu/umd/cs/piccolo/PCamera.java (revision 11)
@@ -59,14 +59,15 @@
  * Each camera maintains a view transform through which it views these
  * layers. Translating and scaling this view transform is how zooming
  * and panning are implemented.
- * <p>
+ * <p/>
  * Cameras are also the point through which all PInputEvents enter
Piccolo. The

  * canvas coordinate system, and the local coordinate system of the
topmost cam
era
  * should always be the same.
- * <p>
+ * <p/>
+ *
+ * @author Jesse Grosjean
+ * @version 1.0
  * @see PLayer
- * @version 1.0
- * @author Jesse Grosjean
  */
 public class PCamera extends PNode {

@@ -393,7 +394,6 @@
                return false;
        }

-
        //****************************************************************
        // View Transform - Methods for accessing the view transform. The
        // view transform is applied before painting and picking the cameras
@@ -502,6 +502,10 @@
                firePropertyChange(PROPERTY_CODE_VIEW_TRANSFORM,
PROPERTY_VIEW_T
RANSFORM, null, viewTransform);
        }

+    public PTransformActivity animateViewToCenterBounds(Rectangle2D
centerBound
s, boolean shouldScaleToFit, long duration) {
+        return animateViewToCenterBounds(centerBounds, shouldScaleToFit,
false,
 duration);
+    }
+
        /**
         * Animate the camera's view from its current transform when the
activit
y
         * starts to a new transform that centers the given bounds in the
camera

@@ -513,18 +517,26 @@
         * bounds fit fully within the cameras view bounds, else the camera
will

         * maintain its original scale.
         */
-       public PTransformActivity animateViewToCenterBounds(Rectangle2D
centerBo
unds, boolean shouldScaleToFit, long duration) {
+    public PTransformActivity animateViewToCenterBounds(Rectangle2D
centerBound
s, boolean shouldScaleToFit, boolean nonRectangularScale, long duration) {
                PBounds viewBounds = getViewBounds();
+        PAffineTransform newTransform = getViewTransform();
                PDimension delta =
viewBounds.deltaRequiredToCenter(centerBounds
);
-               PAffineTransform newTransform = getViewTransform();
                newTransform.translate(delta.width, delta.height);

                if (shouldScaleToFit) {
+            if (nonRectangularScale) {
+                double wS = viewBounds.getWidth() / centerBounds.getWidth();
+                double hS = viewBounds.getHeight() / centerBounds.getHeight();
+                newTransform.translate(centerBounds.getCenterX(),
centerBounds.
getCenterY());
+                newTransform.scale(wS, hS);
+                newTransform.translate(-centerBounds.getCenterX(),
-centerBound
s.getCenterY());
+            } else {
                        double s = Math.min(viewBounds.getWidth() /
centerBounds
.getWidth(), viewBounds.getHeight() / centerBounds.getHeight());
                        if (s != Double.POSITIVE_INFINITY && s != 0) {
                                newTransform.scaleAboutPoint(s,
centerBounds.get
CenterX(), centerBounds.getCenterY());
                        }
                }
+        }

                return animateViewToTransform(newTransform, duration);
        }
@@ -575,6 +587,7 @@
                        public void setTransform(AffineTransform aTransform) {
                                PCamera.this.setViewTransform(aTransform);
                        }
+
                        public void getSourceMatrix(double[] aSource) {
                                PCamera.this.viewTransform.getMatrix(aSource);
                        }
@@ -598,6 +611,7 @@
        public int getViewConstraint() {
                return viewConstraint;
        }
+
        public void setViewConstraint(int constraint) {
                viewConstraint = constraint;
                applyViewConstraints();

Original issue reported on code.google.com by steveonjava on 24 Jun 2008 at 7:54

GoogleCodeExporter commented 9 years ago

Original comment by steveonjava on 25 Jun 2008 at 6:35

GoogleCodeExporter commented 9 years ago
Comment from Michael:

You might reimplement that leaving the existing methods in place and
creating new methods with the boolean nonRectangularScale parameter.
The existing methods forward to the new ones.

In general boolean flags in methods are kind of icky, but I guess
Piccolo already has some.

Original comment by steveonjava on 26 Jun 2008 at 9:38

GoogleCodeExporter commented 9 years ago

Original comment by steveonjava on 2 Jul 2008 at 12:28

GoogleCodeExporter commented 9 years ago

Original comment by steveonjava on 3 Jul 2008 at 5:05

GoogleCodeExporter commented 9 years ago
As I understand the above code, this would set a different scale on the X and Y 
axis.

Then (unless I misunderstood the code) I completely agree that this should be 
done in
an extra method, leaving the existing method in place because it dramatically 
changes
its behaviour (and would surely break some existing client code).

In addition, I may suggest to add other setScaleX() and setScaleY() methods in 
most
components that can be scaled...
At the moment, only setScale(double) is available... sometimes setScale(double,
double) can be used... But having convenience method that only set the scale on 
one
particular axis could be fine...

I have written the code already for some nodes, I can provide support/diff to 
help
supporting "non isomorphic" scaling.

Original comment by lionel.v...@gmail.com on 10 Jul 2009 at 3:53

GoogleCodeExporter commented 9 years ago
Although I think this does allow for maximum flexibility, I can't help but 
wonder if
the payoffs are not worth it. The very concept of node's scale becomes 
meaningless if
this change is allowed.

If we make the suggested changes and then set the X scale of a node to 10 and 
the y
scale to 1, what should getScale() return? I'm not sure there's a meaningful 
response
to the question.

I'd hate to lose such a simple concept at the cost of most flexibility, without
gaining a compelling new use case.

Thoughts?

Original comment by allain.lalonde on 5 Aug 2009 at 12:54

GoogleCodeExporter commented 9 years ago
I vote for moving this to Milestone-2.0

Original comment by heue...@gmail.com on 9 Oct 2009 at 4:06

GoogleCodeExporter commented 9 years ago
Deferring to Milestone-2.0 per email from Steve.

Original comment by heue...@gmail.com on 27 Oct 2009 at 1:02

GoogleCodeExporter commented 9 years ago
Isn't it possible to use a non-rectangular view scale transform via 
setViewTransform?  Does this break any of the assumptions in Piccolo2D?

Original comment by heue...@gmail.com on 24 Aug 2010 at 3:01

GoogleCodeExporter commented 9 years ago
Yes. Possible. And it does break some things.

The definition of PNode#getScale() just applies the transform to a unit length 
and compares the transformed length to the original. So having arbitrary 
transforms would break that function.

Original comment by allain.lalonde on 24 Aug 2010 at 6:29

GoogleCodeExporter commented 9 years ago
Reverting back to New status

Original comment by heue...@gmail.com on 31 Aug 2012 at 8:19

GoogleCodeExporter commented 9 years ago

Original comment by heue...@gmail.com on 31 Aug 2012 at 8:20

GoogleCodeExporter commented 9 years ago

Original comment by heue...@gmail.com on 31 Aug 2012 at 8:22

GoogleCodeExporter commented 9 years ago

Original comment by heue...@gmail.com on 26 Nov 2013 at 11:22