From 9212adbc3808f9b6f72d2279a34013cbfbe20da2 Mon Sep 17 00:00:00 2001 From: payne911 Date: Sun, 12 Jan 2020 14:39:41 -0500 Subject: [PATCH 1/5] Renamed a variable properly. --- .../games/piemenu/individuals/ButtonToggle.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/test/java/com/payne/games/piemenu/individuals/ButtonToggle.java b/src/test/java/com/payne/games/piemenu/individuals/ButtonToggle.java index 91de7bf..bb4eb9b 100644 --- a/src/test/java/com/payne/games/piemenu/individuals/ButtonToggle.java +++ b/src/test/java/com/payne/games/piemenu/individuals/ButtonToggle.java @@ -27,7 +27,7 @@ public class ButtonToggle extends ApplicationAdapter { private Stage stage; private Texture tmpTex; private Batch batch; - private AnimatedPieWidget radGroup; + private AnimatedPieWidget widget; @Override @@ -66,12 +66,12 @@ public void create () { style.circumferenceWidth = 2; style.circumferenceColor = Color.BLACK; style.separatorColor = style.circumferenceColor; - radGroup = new AnimatedPieWidget(whitePixel, style, 110, 50f/110, 315, 270); + widget = new AnimatedPieWidget(whitePixel, style, 110, 50f/110, 315, 270); /* Populating the widget. */ for (int i = 0; i < 8; i++) { Label label = new Label(Integer.toString(i), skin); - radGroup.addActor(label); + widget.addActor(label); } /* Setting up the demo-button. */ @@ -79,16 +79,16 @@ public void create () { textButton.addListener(new ChangeListener() { @Override public void changed(ChangeEvent event, Actor actor) { - radGroup.toggleVisibility(.9f); // 0.9 seconds animation - radGroup.setPosition(textButton.getX(Align.center), + widget.toggleVisibility(.9f); // 0.9 seconds animation + widget.setPosition(textButton.getX(Align.center), textButton.getY(Align.center) - 5, Align.center); } }); root.add(textButton).expand().bottom(); /* Including the Widget in the Stage. */ - stage.addActor(radGroup); - radGroup.setVisible(false); + stage.addActor(widget); + widget.setVisible(false); } From 7466ca43eb2204652143a87b709672510cf29921 Mon Sep 17 00:00:00 2001 From: payne911 Date: Sun, 12 Jan 2020 14:40:17 -0500 Subject: [PATCH 2/5] Fixed some JavaDoc. --- .../java/com/payne/games/piemenu/AnimatedPieMenu.java | 8 ++++++++ .../com/payne/games/piemenu/AnimatedPieWidget.java | 10 +++++++++- src/main/java/com/payne/games/piemenu/PieWidget.java | 11 ++++++----- .../java/com/payne/games/piemenu/RadialGroup.java | 4 ++-- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/payne/games/piemenu/AnimatedPieMenu.java b/src/main/java/com/payne/games/piemenu/AnimatedPieMenu.java index bea7212..69602a7 100644 --- a/src/main/java/com/payne/games/piemenu/AnimatedPieMenu.java +++ b/src/main/java/com/payne/games/piemenu/AnimatedPieMenu.java @@ -28,6 +28,14 @@ * that is why you might end up not seeing the widget despite setting its * visibility to {@code true} if you haven't called the recommended line of code * provided above. + * + * @deprecated Once {@link com.badlogic.gdx.scenes.scene2d.Action Actions} are + * integrated into the library, this class will become obsolete. However, + * the implementation is very easy to use, so it might remain in the code base + * despite Actions being integrated. The reason behind the deprecation is mostly + * because the Animated classes are a hassle to maintain. It's thus more of a + * code-design decision. For users, this is still a very nice class to work with. + * @author Jérémi Grenier-Berthiaume (aka "payne") */ @Deprecated public class AnimatedPieMenu extends PieMenu { diff --git a/src/main/java/com/payne/games/piemenu/AnimatedPieWidget.java b/src/main/java/com/payne/games/piemenu/AnimatedPieWidget.java index cc07b46..ee7f7cd 100644 --- a/src/main/java/com/payne/games/piemenu/AnimatedPieWidget.java +++ b/src/main/java/com/payne/games/piemenu/AnimatedPieWidget.java @@ -11,7 +11,7 @@ /** - * An animated {@link RadialGroup}.
+ * An animated {@link PieWidget}.
* A very simple folding/unfolding animation can be displayed whenever desired.
* Internally uses a {@link #currentAngle} attribute that is used for transitions * between states. Because of that, using {@link #setVisible(boolean)} might not @@ -28,6 +28,14 @@ * that is why you might end up not seeing the widget despite setting its * visibility to {@code true} if you haven't called the recommended line of code * provided above. + * + * @deprecated Once {@link com.badlogic.gdx.scenes.scene2d.Action Actions} are + * integrated into the library, this class will become obsolete. However, + * the implementation is very easy to use, so it might remain in the code base + * despite Actions being integrated. The reason behind the deprecation is mostly + * because the Animated classes are a hassle to maintain. It's thus more of a + * code-design decision. For users, this is still a very nice class to work with. + * @author Jérémi Grenier-Berthiaume (aka "payne") */ @Deprecated public class AnimatedPieWidget extends PieWidget { diff --git a/src/main/java/com/payne/games/piemenu/PieWidget.java b/src/main/java/com/payne/games/piemenu/PieWidget.java index 8581756..a59b268 100644 --- a/src/main/java/com/payne/games/piemenu/PieWidget.java +++ b/src/main/java/com/payne/games/piemenu/PieWidget.java @@ -17,9 +17,9 @@ * A PieWidget aims at providing the user with a simple way to lay out * the contained Actors in a circular fashion. It uses a * {@link ShapeDrawer} to draw certain elements, when necessary.
- * Basically, if you are not finding yourself happy with the results - * coming from using a {@link PieWidgetStyle}, then you might want to - * consider using a simple {@link RadialGroup}. + * Basically, if you do not care about having a {@link PieWidgetStyle + * Style} (i.e. background colors, borders and edges, etc.), then you + * might want to consider using a simple {@link RadialGroup}. * * @author Jérémi Grenier-Berthiaume (aka "payne") */ @@ -37,7 +37,7 @@ public class PieWidget extends RadialGroup { protected ShapeDrawer sd; /** - * The white pixel used to initialized a {@link ShapeDrawer}. + * The white pixel used to initialize a {@link ShapeDrawer}. */ protected TextureRegion whitePixel; @@ -713,7 +713,8 @@ public PieWidgetStyle(PieWidgetStyle style) { /** - * @return the ShapeDrawer used to draw everything but the contained Actors. + * @return the {@link ShapeDrawer} used to draw everything but the contained Actors + * and the Drawables. */ public ShapeDrawer getShapeDrawer() { return sd; diff --git a/src/main/java/com/payne/games/piemenu/RadialGroup.java b/src/main/java/com/payne/games/piemenu/RadialGroup.java index a954e5f..8691a83 100644 --- a/src/main/java/com/payne/games/piemenu/RadialGroup.java +++ b/src/main/java/com/payne/games/piemenu/RadialGroup.java @@ -229,7 +229,7 @@ public boolean removeActor(Actor actor) { * Here is an example: *
      * {@code
-     * RadialGroup myWidget = new RadialGroup(shapeDrawer, myStyle, 77) {
+     * RadialGroup myWidget = new RadialGroup(77) {
      *     public float getActorDistanceFromCenter(Actor actor) {
      *         // We want the Actors to be placed closer to the edge than the default value
      *         return getAmountOfChildren() > 1
@@ -259,7 +259,7 @@ public float getActorDistanceFromCenter(Actor actor) {
      * Here is an example:
      * 
      * {@code
-     * RadialGroup myWidget = new RadialGroup(shapeDrawer, myStyle, 77) {
+     * RadialGroup myWidget = new RadialGroup(77) {
      *     public void modifyActor(Actor actor, float degreesPerChild, float actorDistanceFromCenter) {
      *         float size = getEstimatedRadiusAt(degreesPerChild, actorDistanceFromCenter);
      *         size *= 1.26f; // adjusting the returned value to our likes

From 2c514aa8629fd2e800e3e3000feb3d88d3e15fb9 Mon Sep 17 00:00:00 2001
From: payne911 
Date: Sun, 12 Jan 2020 14:47:11 -0500
Subject: [PATCH 3/5] Added an AnimatedRadialGroup

---
 .../games/piemenu/AnimatedRadialGroup.java    | 342 ++++++++++++++++++
 1 file changed, 342 insertions(+)
 create mode 100644 src/main/java/com/payne/games/piemenu/AnimatedRadialGroup.java

diff --git a/src/main/java/com/payne/games/piemenu/AnimatedRadialGroup.java b/src/main/java/com/payne/games/piemenu/AnimatedRadialGroup.java
new file mode 100644
index 0000000..aef69ac
--- /dev/null
+++ b/src/main/java/com/payne/games/piemenu/AnimatedRadialGroup.java
@@ -0,0 +1,342 @@
+package com.payne.games.piemenu;
+
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.math.Vector2;
+import com.badlogic.gdx.scenes.scene2d.Actor;
+import com.badlogic.gdx.utils.Align;
+import java.util.HashMap;
+
+
+/**
+ * An animated {@link RadialGroup}.
+ * A very simple folding/unfolding animation can be displayed whenever desired.
+ * Internally uses a {@link #currentAngle} attribute that is used for transitions + * between states. Because of that, using {@link #setVisible(boolean)} might not + * always reveal the Widget: you would have to ensure to call a setter before: + *
+ * {@code
+ * myMenu.setCurrentAngle(myMenu.getStyle().totalDegreesDrawn);
+ * myMenu.setVisible(true);
+ * }
+ * 
+ * The value of {@link #currentAngle} dictates the currently revealed amount of + * angles, out of the total amount of degrees to be drawn. Its value is of 0 + * when the class is first initialized, and after a closing animation ended: + * that is why you might end up not seeing the widget despite setting its + * visibility to {@code true} if you haven't called the recommended line of code + * provided above. + * + * @deprecated Once {@link com.badlogic.gdx.scenes.scene2d.Action Actions} are + * integrated into the library, this class will become obsolete. However, + * the implementation is very easy to use, so it might remain in the code base + * despite Actions being integrated. The reason behind the deprecation is mostly + * because the Animated classes are a hassle to maintain. It's thus more of a + * code-design decision. For users, this is still a very nice class to work with. + * @author Jérémi Grenier-Berthiaume (aka "payne") + */ +@Deprecated +public class AnimatedRadialGroup extends RadialGroup { + + /** + * Duration of the animation. + */ + private float duration; + + + /* For internal use. */ + private boolean isOpening = false; + private boolean isClosing = false; + private float currentAngle = 0; // reused for transitions between entry and exit + private static Vector2 vector2 = new Vector2(); + private HashMap originalColors = new HashMap<>(); + + + + + + /** + * See {@link AnimatedRadialGroup} for a description. + * + * @param preferredRadius the {@link #preferredRadius} that defines the + * size of the widget. + */ + public AnimatedRadialGroup(float preferredRadius) { + super(preferredRadius); + } + + /** + * See {@link AnimatedRadialGroup} for a description. + * + * @param preferredRadius the {@link #preferredRadius} that defines the + * size of the widget. + * @param innerRadiusPercent the {@link #innerRadiusPercent} that defines + * the percentage of the radius that is cut off, + * starting from the center of the widget. + */ + public AnimatedRadialGroup(float preferredRadius, + float innerRadiusPercent) { + super(preferredRadius, innerRadiusPercent); + } + + /** + * See {@link AnimatedRadialGroup} for a description. + * + * @param preferredRadius the {@link #preferredRadius} that defines the + * size of the widget. + * @param innerRadiusPercent the {@link #innerRadiusPercent} that defines + * the percentage of the radius that is cut off, + * starting from the center of the widget. + * @param startDegreesOffset the {@link #startDegreesOffset} that defines + * how far from the origin the drawing begins. + */ + public AnimatedRadialGroup(float preferredRadius, + float innerRadiusPercent, float startDegreesOffset) { + super(preferredRadius, innerRadiusPercent, startDegreesOffset); + } + + /** + * See {@link AnimatedRadialGroup} for a description. + * + * @param preferredRadius the {@link #preferredRadius} that defines the + * size of the widget. + * @param innerRadiusPercent the {@link #innerRadiusPercent} that defines + * the percentage of the radius that is cut off, + * starting from the center of the widget. + * @param startDegreesOffset the {@link #startDegreesOffset} that defines + * how far from the origin the drawing begins. + * @param totalDegreesDrawn the {@link #totalDegreesDrawn} that defines how + * many degrees the widget will span, starting from + * its {@link #startDegreesOffset}. + */ + public AnimatedRadialGroup(float preferredRadius, + float innerRadiusPercent, float startDegreesOffset, float totalDegreesDrawn) { + super(preferredRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); + } + + + + + + + @Override + public void layout() { + updateOrigin(); // for rotations to happen around the actual center + + boolean notAnimated = !isCurrentlyAnimated() && !originalColors.isEmpty(); + float openingPercentage = currentAngle / totalDegreesDrawn; + float degreesPerChild = currentAngle / getAmountOfChildren(); + float half = 1f / 2; + + for (int i = 0; i < getAmountOfChildren(); i++) { + Actor actor = getChildren().get(i); + float dist = getActorDistanceFromCenter(actor); + vector2.set(dist, 0); + vector2.rotate(degreesPerChild*(i + half) + startDegreesOffset); + modifyActor(actor, degreesPerChild, dist); // overridden by user + actor.setPosition(vector2.x + getWidth()/2, vector2.y + getHeight()/2, Align.center); + + /* Updating alpha (fade-in animation). */ + if(isCurrentlyAnimated()) { + if (!originalColors.containsKey(actor)) + originalColors.put(actor, new Color(actor.getColor())); + Color color = originalColors.get(actor); + actor.setColor(color.r, color.g, color.b, color.a * openingPercentage); + + /* Restoring the colors' state. */ + } else if(notAnimated) { + actor.setColor(originalColors.get(actor)); + } + } + if (notAnimated) { + originalColors.clear(); + } + } + + + /** + * Gets the widget to transition into an opening animation from its + * currently drawn angle (i.e. {@link #currentAngle}). + * + * @param durationSeconds How long the animation will take to finish. + */ + public void transitionToOpening(float durationSeconds) { + duration = durationSeconds/1000f; + isOpening = true; + isClosing = false; + setVisible(true); + } + + /** + * Gets the widget to start an opening animation from the beginning. + * + * @param durationSeconds How long the animation will take to finish. + */ + public void animateOpening(float durationSeconds) { + currentAngle = 0; + transitionToOpening(durationSeconds); + } + + /** + * Gets the widget to transition into a closing animation from its + * currently drawn angle (i.e. {@link #currentAngle}). + * + * @param durationSeconds How long the animation will take to finish. + */ + public void transitionToClosing(float durationSeconds) { + duration = durationSeconds/1000f; + isClosing = true; + isOpening = false; + } + + /** + * Gets the widget to start a closing animation from the beginning (i.e. + * from its fully opened state). + * + * @param durationSeconds How long the animation will take to finish. + */ + public void animateClosing(float durationSeconds) { + currentAngle = totalDegreesDrawn; + transitionToClosing(durationSeconds); + } + + /** + * Transitions from the current state to the other.
+ * If the widget is opening, it will now be closing, for example.
+ * Visibility plays a role in determining the current state (for example, + * if the widget is not visible, it is assumed that it's as if it was closed). + * + * @param durationSeconds How long the animation will take to finish. + */ + public void toggleVisibility(float durationSeconds) { + if(isOpening || (isVisible() && !isClosing)) { + transitionToClosing(durationSeconds); + } else if(isClosing || !isVisible()) { + transitionToOpening(durationSeconds); + } + } + + /** + * @return {@code true} if the widget is being closed or opened.
+ * {@code false} otherwise. + */ + public boolean isCurrentlyAnimated() { + return (isOpening || isClosing); + } + + @Override + public void act(float delta) { + super.act(delta); + + if(isCurrentlyAnimated()) { + float speed = delta / duration; + + /* Opening. */ + if(isOpening) { + currentAngle += speed; + if(currentAngle >= totalDegreesDrawn) { // finishing the animation + currentAngle = totalDegreesDrawn; + isOpening = false; + } + + /* Closing. */ + } else { + currentAngle -= speed; + if(currentAngle <= 0) { // finishing the animation + currentAngle = 0; + isClosing = false; + setVisible(false); + } + } + + /* Updates children. Calls `layout()`. */ + invalidate(); + } + } + + + + + + + + /** + * @return the duration of the animation. + */ + public float getDuration() { + return duration; + } + + /** + * Setting the duration to 0 will make any currently-running animation end + * at the next {@code render()} call. + * + * @param duration a value corresponding to {@code durationInSecond/1000f}. + */ + public void setDuration(float duration) { + if(duration < 0) + throw new IllegalArgumentException("duration cannot be negative."); + this.duration = duration; + } + + /** + * @return {@code true} only when the Widget is currently running an opening + * animation.
+ * To be more precise, for example: when an opening animation ends, + * this returns {@code false} + */ + public boolean isOpening() { + return isOpening; + } + + /** + * @return {@code true} only when the Widget is currently running a closing + * animation.
+ * To be more precise, for example: when a closing animation ends, + * this returns {@code false} + */ + public boolean isClosing() { + return isClosing; + } + + /** + * After a closing animation, its value is equal to 0.
+ * After an opening animation, its value is equal to + * {@code style.totalDegreesDrawn}. + * + * @return an angle in between 0 and {@code style.totalDegreesDrawn}. It + * represents the internal state of how far in an animation the widget + * is at. If its value is 15, for example, it means that only 15 + * degrees, out of the total amount of degrees the widget should + * take, are being rendered on the screen. + */ + public float getCurrentAngle() { + return currentAngle; + } + + /** + * Use this if you want to manipulate the internal state of how much of the + * widget should be drawn.
+ * After a closing animation, its value is equal to 0.
+ * After an opening animation, its value is equal to + * {@code style.totalDegreesDrawn}.
+ * This means that the accepted values are from 0 to style.totalDegreesDrawn, + * inclusively.
+ *
+ * It is recommended to use + *
+     * {@code
+     * myMenu.setCurrentAngle(myMenu.getStyle().totalDegreesDrawn);
+     * myMenu.setVisible(true);
+     * }
+     * 
+ * when you want to display the widget to your users, for example. + * + * @param currentAngle amount of angles, out of the total, which should + * currently be displayed. + */ + public void setCurrentAngle(float currentAngle) { + if(currentAngle >= totalDegreesDrawn || currentAngle <= 0) + throw new IllegalArgumentException("currentAngle must be between 0 and totalDegreesDrawn."); + this.currentAngle = currentAngle; + } +} From 84092bdaa96b8e6a96a337c19191cec0ecb76415 Mon Sep 17 00:00:00 2001 From: payne911 Date: Sun, 12 Jan 2020 14:56:00 -0500 Subject: [PATCH 4/5] Bumping version in preparation for release --- README.md | 2 +- build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 11cff33..f875395 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ allprojects { ext { ... - pieMenuVersion = '4.0.0' + pieMenuVersion = '4.1.0' } repositories { diff --git a/build.gradle b/build.gradle index cee4848..fe1dbc8 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,7 @@ apply from: 'publish.gradle' sourceCompatibility = 1.8 def projectName = 'pie-menu' -version '4.0.0' +version '4.1.0' group 'com.payne.games' def gdxVersion = '1.9.10' From a5fb252a92041e56b07a44b3c448af74a7bb1170 Mon Sep 17 00:00:00 2001 From: payne911 Date: Sun, 12 Jan 2020 15:01:41 -0500 Subject: [PATCH 5/5] Fixed README for merge --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f875395..51cff9d 100644 --- a/README.md +++ b/README.md @@ -62,13 +62,13 @@ To use this in your gradle project, add the version number and jitpack repositor allprojects { ext { - ... - pieMenuVersion = '4.1.0' + ... + pieMenuVersion = '4.1.0' // add this line } repositories { - ... - maven { url 'https://jitpack.io' } + ... + maven { url 'https://jitpack.io' } } } ```