diff --git a/CHANGES b/CHANGES index 4299678..68cbbb6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,11 +1,18 @@ -(UPCOMING) [4.0.0] +[4.0.0] - A `Batch` does not need to be passed to the constructors anymore. - Introduced `PieWidget` in the new design: the `RadialGroup` now doesn't deal in any way with the `ShapeDrawer`. - `getMaxDiameter` has been renamed to `getCurrentDiameter`. - `getMaxRadius` has been renamed to `getCurrentRadius`. +- `minRadius` has been renamed to `preferredRadius`. +- Introduced a new `individuals` demo (named "RadialButtons") to showcase the new `RadialGroup` class. +- Changed the way the scene2d `hit` method works with the widget. +- Fixed the `hit` for when a contained Actor extends beyond the limits of the widget itself. +- Fixed `RadialGroup` containing other `PieMenu`. +- Fixed non-regular width and height values on Animated widgets. +- Fixed `centerOnActor` method used on an Actor that was contained within a `Group`. [3.1.0] -- Hotfix for "floating" `Group` that contained `RadialGroup`. +- Fixed the "floating" `Group` that contained `RadialGroup`. - More efficient evaluation for the reset of the hover on mouse-exit. - The `background` image can now be a `Drawable` as well (but keep in mind that `Drawable` cannot be rotated). diff --git a/README.md b/README.md index ebd3b3b..11cff33 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ --- -A library for [libGDX](https://libgdx.badlogicgames.com/), an open-source game development application framework written in Java. +A library to obtain a circular WidgetGroup within [libGDX](https://libgdx.badlogicgames.com/), an open-source game development application framework written in Java. Aims at providing users with the so-called `RadialGroup`: it is a simple container that places its children `Actors` in a circular fashion. @@ -63,7 +63,7 @@ allprojects { ext { ... - pieMenuVersion = '3.1.0' + pieMenuVersion = '4.0.0' } repositories { @@ -99,7 +99,7 @@ The basic idea looks like this: /* Setting up and creating the widget. */ PieMenu.PieMenuStyle style = new PieMenu.PieMenuStyle(); style.sliceColor = new Color(.33f,.33f,.33f,1); // "style" variables affect the way the widget looks -PieMenu menu = new PieMenu(batch, skin.getRegion("white"), style, 80); // "white" would be a 1x1 white pixel +PieMenu menu = new PieMenu(skin.getRegion("white"), style, 80); // "white" would be a 1x1 white pixel /* Adding a listener. */ menu.addListener(new ChangeListener() { @@ -122,7 +122,7 @@ stage.addActor(menu); And *voilà*! ### [Wiki](https://github.com/payne911/PieMenu/wiki) -This library offers you many types of behaviors related to pie menus. Many of those are well-documented in the Wiki (with description, code and gif), so make sure to check it out. +This library offers you many types of behaviors related to pie-menus. Many of those are well-documented in the Wiki (with description, code and gif), so make sure to check it out. More specifically, you might be interested in: * [Complete examples of code](https://github.com/payne911/PieMenu/wiki/Examples), along with textual descriptions of the expected behavior diff --git a/build.gradle b/build.gradle index 8445944..e4aaeef 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,7 @@ apply from: 'publish.gradle' sourceCompatibility = 1.8 def projectName = 'pie-menu' -version '3.1.0' +version '4.0.0' group 'com.payne.games' def gdxVersion = '1.9.10' diff --git a/src/main/java/com/payne/games/piemenu/AnimatedPieMenu.java b/src/main/java/com/payne/games/piemenu/AnimatedPieMenu.java index 85db688..bea7212 100644 --- a/src/main/java/com/payne/games/piemenu/AnimatedPieMenu.java +++ b/src/main/java/com/payne/games/piemenu/AnimatedPieMenu.java @@ -7,7 +7,6 @@ import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.utils.Align; - import java.util.HashMap; @@ -53,59 +52,59 @@ public class AnimatedPieMenu extends PieMenu { /** * See {@link AnimatedPieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param style defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @param preferredRadius the {@link #preferredRadius} that defines the + * size of the widget. */ - public AnimatedPieMenu(final Batch batch, final TextureRegion whitePixel, - PieMenuStyle style, float minRadius) { - super(batch, whitePixel, style, minRadius); + public AnimatedPieMenu(final TextureRegion whitePixel, + PieMenuStyle style, float preferredRadius) { + super(whitePixel, style, preferredRadius); } /** * See {@link AnimatedPieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param style defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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 AnimatedPieMenu(final Batch batch, final TextureRegion whitePixel, - PieMenuStyle style, float minRadius, + public AnimatedPieMenu(final TextureRegion whitePixel, + PieMenuStyle style, float preferredRadius, float innerRadiusPercent) { - super(batch, whitePixel, style, minRadius, innerRadiusPercent); + super(whitePixel, style, preferredRadius, innerRadiusPercent); } /** * See {@link AnimatedPieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param style defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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 AnimatedPieMenu(final Batch batch, final TextureRegion whitePixel, - PieMenuStyle style, float minRadius, + public AnimatedPieMenu(final TextureRegion whitePixel, + PieMenuStyle style, float preferredRadius, float innerRadiusPercent, float startDegreesOffset) { - super(batch, whitePixel, style, minRadius, innerRadiusPercent, startDegreesOffset); + super(whitePixel, style, preferredRadius, innerRadiusPercent, startDegreesOffset); } /** * See {@link AnimatedPieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param style defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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. @@ -115,67 +114,67 @@ public AnimatedPieMenu(final Batch batch, final TextureRegion whitePixel, * many degrees the widget will span, starting from * its {@link #startDegreesOffset}. */ - public AnimatedPieMenu(final Batch batch, final TextureRegion whitePixel, - PieMenuStyle style, float minRadius, + public AnimatedPieMenu(final TextureRegion whitePixel, + PieMenuStyle style, float preferredRadius, float innerRadiusPercent, float startDegreesOffset, float totalDegreesDrawn) { - super(batch, whitePixel, style, minRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); + super(whitePixel, style, preferredRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); } /** * See {@link AnimatedPieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @param preferredRadius the {@link #preferredRadius} that defines the + * size of the widget. */ - public AnimatedPieMenu(final Batch batch, final TextureRegion whitePixel, - Skin skin, float minRadius) { - super(batch, whitePixel, skin, minRadius); + public AnimatedPieMenu(final TextureRegion whitePixel, + Skin skin, float preferredRadius) { + super(whitePixel, skin, preferredRadius); } /** * See {@link AnimatedPieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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 AnimatedPieMenu(final Batch batch, final TextureRegion whitePixel, - Skin skin, float minRadius, float innerRadiusPercent) { - super(batch, whitePixel, skin, minRadius, innerRadiusPercent); + public AnimatedPieMenu(final TextureRegion whitePixel, + Skin skin, float preferredRadius, float innerRadiusPercent) { + super(whitePixel, skin, preferredRadius, innerRadiusPercent); } /** * See {@link AnimatedPieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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 AnimatedPieMenu(final Batch batch, final TextureRegion whitePixel, - Skin skin, float minRadius, float innerRadiusPercent, + public AnimatedPieMenu(final TextureRegion whitePixel, + Skin skin, float preferredRadius, float innerRadiusPercent, float startDegreesOffset) { - super(batch, whitePixel, skin, minRadius, innerRadiusPercent, startDegreesOffset); + super(whitePixel, skin, preferredRadius, innerRadiusPercent, startDegreesOffset); } /** * See {@link AnimatedPieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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. @@ -185,72 +184,72 @@ public AnimatedPieMenu(final Batch batch, final TextureRegion whitePixel, * many degrees the widget will span, starting from * its {@link #startDegreesOffset}. */ - public AnimatedPieMenu(final Batch batch, final TextureRegion whitePixel, - Skin skin, float minRadius, float innerRadiusPercent, + public AnimatedPieMenu(final TextureRegion whitePixel, + Skin skin, float preferredRadius, float innerRadiusPercent, float startDegreesOffset, float totalDegreesDrawn) { - super(batch, whitePixel, skin, minRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); + super(whitePixel, skin, preferredRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); } /** * See {@link AnimatedPieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. * @param style the name of the style to be extracted from the skin. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @param preferredRadius the {@link #preferredRadius} that defines the + * size of the widget. */ - public AnimatedPieMenu(final Batch batch, final TextureRegion whitePixel, - Skin skin, String style, float minRadius) { - super(batch, whitePixel, skin, style, minRadius); + public AnimatedPieMenu(final TextureRegion whitePixel, + Skin skin, String style, float preferredRadius) { + super(whitePixel, skin, style, preferredRadius); } /** * See {@link AnimatedPieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. * @param style the name of the style to be extracted from the skin. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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 AnimatedPieMenu(final Batch batch, final TextureRegion whitePixel, - Skin skin, String style, float minRadius, + public AnimatedPieMenu(final TextureRegion whitePixel, + Skin skin, String style, float preferredRadius, float innerRadiusPercent) { - super(batch, whitePixel, skin, style, minRadius, innerRadiusPercent); + super(whitePixel, skin, style, preferredRadius, innerRadiusPercent); } /** * See {@link AnimatedPieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. * @param style the name of the style to be extracted from the skin. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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 AnimatedPieMenu(final Batch batch, final TextureRegion whitePixel, - Skin skin, String style, float minRadius, + public AnimatedPieMenu(final TextureRegion whitePixel, + Skin skin, String style, float preferredRadius, float innerRadiusPercent, float startDegreesOffset) { - super(batch, whitePixel, skin, style, minRadius, innerRadiusPercent, startDegreesOffset); + super(whitePixel, skin, style, preferredRadius, innerRadiusPercent, startDegreesOffset); } /** * See {@link AnimatedPieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. * @param style the name of the style to be extracted from the skin. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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. @@ -260,10 +259,10 @@ public AnimatedPieMenu(final Batch batch, final TextureRegion whitePixel, * many degrees the widget will span, starting from * its {@link #startDegreesOffset}. */ - public AnimatedPieMenu(final Batch batch, final TextureRegion whitePixel, - Skin skin, String style, float minRadius, + public AnimatedPieMenu(final TextureRegion whitePixel, + Skin skin, String style, float preferredRadius, float innerRadiusPercent, float startDegreesOffset, float totalDegreesDrawn) { - super(batch, whitePixel, skin, style, minRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); + super(whitePixel, skin, style, preferredRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); } @@ -287,7 +286,7 @@ public void layout() { vector2.set(dist, 0); vector2.rotate(degreesPerChild*(i + half) + startDegreesOffset); modifyActor(actor, degreesPerChild, dist); // overridden by user - actor.setPosition(vector2.x+getMaxRadius(), vector2.y+getMaxRadius(), Align.center); + actor.setPosition(vector2.x + getWidth()/2, vector2.y + getHeight()/2, Align.center); /* Updating alpha (fade-in animation). */ if(isCurrentlyAnimated()) { diff --git a/src/main/java/com/payne/games/piemenu/AnimatedRadialGroup.java b/src/main/java/com/payne/games/piemenu/AnimatedPieWidget.java similarity index 70% rename from src/main/java/com/payne/games/piemenu/AnimatedRadialGroup.java rename to src/main/java/com/payne/games/piemenu/AnimatedPieWidget.java index e5a8ce4..cc07b46 100644 --- a/src/main/java/com/payne/games/piemenu/AnimatedRadialGroup.java +++ b/src/main/java/com/payne/games/piemenu/AnimatedPieWidget.java @@ -7,7 +7,6 @@ import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.utils.Align; - import java.util.HashMap; @@ -31,7 +30,7 @@ * provided above. */ @Deprecated -public class AnimatedRadialGroup extends RadialGroup { +public class AnimatedPieWidget extends PieWidget { /** * Duration of the animation. @@ -51,61 +50,61 @@ public class AnimatedRadialGroup extends RadialGroup { /** - * See {@link AnimatedRadialGroup} for a description. + * See {@link AnimatedPieWidget} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param style defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @param preferredRadius the {@link #preferredRadius} that defines the + * size of the widget. */ - public AnimatedRadialGroup(final Batch batch, final TextureRegion whitePixel, - RadialGroupStyle style, float minRadius) { - super(batch, whitePixel, style, minRadius); + public AnimatedPieWidget(final TextureRegion whitePixel, + PieWidgetStyle style, float preferredRadius) { + super(whitePixel, style, preferredRadius); } /** - * See {@link AnimatedRadialGroup} for a description. + * See {@link AnimatedPieWidget} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param style defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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(final Batch batch, final TextureRegion whitePixel, - RadialGroupStyle style, float minRadius, - float innerRadiusPercent) { - super(batch, whitePixel, style, minRadius, innerRadiusPercent); + public AnimatedPieWidget(final TextureRegion whitePixel, + PieWidgetStyle style, float preferredRadius, + float innerRadiusPercent) { + super(whitePixel, style, preferredRadius, innerRadiusPercent); } /** - * See {@link AnimatedRadialGroup} for a description. + * See {@link AnimatedPieWidget} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param style defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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(final Batch batch, final TextureRegion whitePixel, - RadialGroupStyle style, float minRadius, - float innerRadiusPercent, float startDegreesOffset) { - super(batch, whitePixel, style, minRadius, innerRadiusPercent, startDegreesOffset); + public AnimatedPieWidget(final TextureRegion whitePixel, + PieWidgetStyle style, float preferredRadius, + float innerRadiusPercent, float startDegreesOffset) { + super(whitePixel, style, preferredRadius, innerRadiusPercent, startDegreesOffset); } /** - * See {@link AnimatedRadialGroup} for a description. + * See {@link AnimatedPieWidget} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param style defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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. @@ -115,67 +114,67 @@ public AnimatedRadialGroup(final Batch batch, final TextureRegion whitePixel, * many degrees the widget will span, starting from * its {@link #startDegreesOffset}. */ - public AnimatedRadialGroup(final Batch batch, final TextureRegion whitePixel, - RadialGroupStyle style, float minRadius, - float innerRadiusPercent, float startDegreesOffset, float totalDegreesDrawn) { - super(batch, whitePixel, style, minRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); + public AnimatedPieWidget(final TextureRegion whitePixel, + PieWidgetStyle style, float preferredRadius, + float innerRadiusPercent, float startDegreesOffset, float totalDegreesDrawn) { + super(whitePixel, style, preferredRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); } /** - * See {@link AnimatedRadialGroup} for a description. + * See {@link AnimatedPieWidget} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @param preferredRadius the {@link #preferredRadius} that defines the + * size of the widget. */ - public AnimatedRadialGroup(final Batch batch, final TextureRegion whitePixel, - Skin skin, float minRadius) { - super(batch, whitePixel, skin, minRadius); + public AnimatedPieWidget(final TextureRegion whitePixel, + Skin skin, float preferredRadius) { + super(whitePixel, skin, preferredRadius); } /** - * See {@link AnimatedRadialGroup} for a description. + * See {@link AnimatedPieWidget} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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(final Batch batch, final TextureRegion whitePixel, - Skin skin, float minRadius, float innerRadiusPercent) { - super(batch, whitePixel, skin, minRadius, innerRadiusPercent); + public AnimatedPieWidget(final TextureRegion whitePixel, + Skin skin, float preferredRadius, float innerRadiusPercent) { + super(whitePixel, skin, preferredRadius, innerRadiusPercent); } /** - * See {@link AnimatedRadialGroup} for a description. + * See {@link AnimatedPieWidget} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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(final Batch batch, final TextureRegion whitePixel, - Skin skin, float minRadius, float innerRadiusPercent, - float startDegreesOffset) { - super(batch, whitePixel, skin, minRadius, innerRadiusPercent, startDegreesOffset); + public AnimatedPieWidget(final TextureRegion whitePixel, + Skin skin, float preferredRadius, float innerRadiusPercent, + float startDegreesOffset) { + super(whitePixel, skin, preferredRadius, innerRadiusPercent, startDegreesOffset); } /** - * See {@link AnimatedRadialGroup} for a description. + * See {@link AnimatedPieWidget} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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. @@ -185,72 +184,72 @@ public AnimatedRadialGroup(final Batch batch, final TextureRegion whitePixel, * many degrees the widget will span, starting from * its {@link #startDegreesOffset}. */ - public AnimatedRadialGroup(final Batch batch, final TextureRegion whitePixel, - Skin skin, float minRadius, float innerRadiusPercent, - float startDegreesOffset, float totalDegreesDrawn) { - super(batch, whitePixel, skin, minRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); + public AnimatedPieWidget(final TextureRegion whitePixel, + Skin skin, float preferredRadius, float innerRadiusPercent, + float startDegreesOffset, float totalDegreesDrawn) { + super(whitePixel, skin, preferredRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); } /** - * See {@link AnimatedRadialGroup} for a description. + * See {@link AnimatedPieWidget} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. * @param style the name of the style to be extracted from the skin. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @param preferredRadius the {@link #preferredRadius} that defines the + * size of the widget. */ - public AnimatedRadialGroup(final Batch batch, final TextureRegion whitePixel, - Skin skin, String style, float minRadius) { - super(batch, whitePixel, skin, style, minRadius); + public AnimatedPieWidget(final TextureRegion whitePixel, + Skin skin, String style, float preferredRadius) { + super(whitePixel, skin, style, preferredRadius); } /** - * See {@link AnimatedRadialGroup} for a description. + * See {@link AnimatedPieWidget} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. * @param style the name of the style to be extracted from the skin. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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(final Batch batch, final TextureRegion whitePixel, - Skin skin, String style, float minRadius, - float innerRadiusPercent) { - super(batch, whitePixel, skin, style, minRadius, innerRadiusPercent); + public AnimatedPieWidget(final TextureRegion whitePixel, + Skin skin, String style, float preferredRadius, + float innerRadiusPercent) { + super(whitePixel, skin, style, preferredRadius, innerRadiusPercent); } /** - * See {@link AnimatedRadialGroup} for a description. + * See {@link AnimatedPieWidget} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. * @param style the name of the style to be extracted from the skin. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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(final Batch batch, final TextureRegion whitePixel, - Skin skin, String style, float minRadius, - float innerRadiusPercent, float startDegreesOffset) { - super(batch, whitePixel, skin, style, minRadius, innerRadiusPercent, startDegreesOffset); + public AnimatedPieWidget(final TextureRegion whitePixel, + Skin skin, String style, float preferredRadius, + float innerRadiusPercent, float startDegreesOffset) { + super(whitePixel, skin, style, preferredRadius, innerRadiusPercent, startDegreesOffset); } /** - * See {@link AnimatedRadialGroup} for a description. + * See {@link AnimatedPieWidget} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. * @param style the name of the style to be extracted from the skin. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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. @@ -260,11 +259,11 @@ public AnimatedRadialGroup(final Batch batch, final TextureRegion whitePixel, * many degrees the widget will span, starting from * its {@link #startDegreesOffset}. */ - public AnimatedRadialGroup(final Batch batch, final TextureRegion whitePixel, - Skin skin, String style, float minRadius, - float innerRadiusPercent, float startDegreesOffset, - float totalDegreesDrawn) { - super(batch, whitePixel, skin, style, minRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); + public AnimatedPieWidget(final TextureRegion whitePixel, + Skin skin, String style, float preferredRadius, + float innerRadiusPercent, float startDegreesOffset, + float totalDegreesDrawn) { + super(whitePixel, skin, style, preferredRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); } @@ -287,7 +286,7 @@ public void layout() { vector2.set(dist, 0); vector2.rotate(degreesPerChild*(i + half) + startDegreesOffset); modifyActor(actor, degreesPerChild, dist); // overridden by user - actor.setPosition(vector2.x+getMaxRadius(), vector2.y+getMaxRadius(), Align.center); + actor.setPosition(vector2.x + getWidth()/2, vector2.y + getHeight()/2, Align.center); /* Updating alpha (fade-in animation). */ if(isCurrentlyAnimated()) { diff --git a/src/main/java/com/payne/games/piemenu/PieMenu.java b/src/main/java/com/payne/games/piemenu/PieMenu.java index 8b39908..e14da9e 100644 --- a/src/main/java/com/payne/games/piemenu/PieMenu.java +++ b/src/main/java/com/payne/games/piemenu/PieMenu.java @@ -2,7 +2,6 @@ import com.badlogic.gdx.Input; import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.scenes.scene2d.Actor; @@ -18,12 +17,13 @@ /** - * A PieMenu reuses the {@link RadialGroup}'s functionalities to provide a way - * to interact with the contained Actors through the "hit-box" of the slices. + * A PieMenu reuses the {@link PieWidget}'s functionalities to provide a way + * to interact with the contained Actors through the "hit-box" of the slices.
+ * Basically, each slice ends up acting like a button. * * @author Jérémi Grenier-Berthiaume (aka "payne") */ -public class PieMenu extends RadialGroup { +public class PieMenu extends PieWidget { /** * This listener controls the interactions with the {@link PieMenu}.
@@ -111,62 +111,62 @@ protected void constructorsCommon() { /** * See {@link PieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param style defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @param preferredRadius the {@link #preferredRadius} that defines the + * size of the widget. */ - public PieMenu(final Batch batch, final TextureRegion whitePixel, - PieMenuStyle style, float minRadius) { - super(batch, whitePixel, minRadius); + public PieMenu(final TextureRegion whitePixel, + PieMenuStyle style, float preferredRadius) { + super(whitePixel, preferredRadius); setStyle(style); } /** * See {@link PieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param style defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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 PieMenu(final Batch batch, final TextureRegion whitePixel, - PieMenuStyle style, float minRadius, + public PieMenu(final TextureRegion whitePixel, + PieMenuStyle style, float preferredRadius, float innerRadiusPercent) { - super(batch, whitePixel, minRadius, innerRadiusPercent); + super(whitePixel, preferredRadius, innerRadiusPercent); setStyle(style); } /** * See {@link PieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param style defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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 PieMenu(final Batch batch, final TextureRegion whitePixel, - PieMenuStyle style, float minRadius, + public PieMenu(final TextureRegion whitePixel, + PieMenuStyle style, float preferredRadius, float innerRadiusPercent, float startDegreesOffset) { - super(batch, whitePixel, minRadius, innerRadiusPercent, startDegreesOffset); + super(whitePixel, preferredRadius, innerRadiusPercent, startDegreesOffset); setStyle(style); } /** * See {@link PieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param style defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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. @@ -176,72 +176,72 @@ public PieMenu(final Batch batch, final TextureRegion whitePixel, * many degrees the widget will span, starting from * its {@link #startDegreesOffset}. */ - public PieMenu(final Batch batch, final TextureRegion whitePixel, - PieMenuStyle style, float minRadius, + public PieMenu(final TextureRegion whitePixel, + PieMenuStyle style, float preferredRadius, float innerRadiusPercent, float startDegreesOffset, float totalDegreesDrawn) { - super(batch, whitePixel, minRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); + super(whitePixel, preferredRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); setStyle(style); } /** * See {@link PieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @param preferredRadius the {@link #preferredRadius} that defines the + * size of the widget. */ - public PieMenu(final Batch batch, final TextureRegion whitePixel, - Skin skin, float minRadius) { - super(batch, whitePixel, minRadius); + public PieMenu(final TextureRegion whitePixel, + Skin skin, float preferredRadius) { + super(whitePixel, preferredRadius); setStyle(skin.get(PieMenuStyle.class)); } /** * See {@link PieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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 PieMenu(final Batch batch, final TextureRegion whitePixel, - Skin skin, float minRadius, + public PieMenu(final TextureRegion whitePixel, + Skin skin, float preferredRadius, float innerRadiusPercent) { - super(batch, whitePixel, minRadius, innerRadiusPercent); + super(whitePixel, preferredRadius, innerRadiusPercent); setStyle(skin.get(PieMenuStyle.class)); } /** * See {@link PieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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 PieMenu(final Batch batch, final TextureRegion whitePixel, - Skin skin, float minRadius, + public PieMenu(final TextureRegion whitePixel, + Skin skin, float preferredRadius, float innerRadiusPercent, float startDegreesOffset) { - super(batch, whitePixel, minRadius, innerRadiusPercent, startDegreesOffset); + super(whitePixel, preferredRadius, innerRadiusPercent, startDegreesOffset); setStyle(skin.get(PieMenuStyle.class)); } /** * See {@link PieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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. @@ -251,76 +251,76 @@ public PieMenu(final Batch batch, final TextureRegion whitePixel, * many degrees the widget will span, starting from * its {@link #startDegreesOffset}. */ - public PieMenu(final Batch batch, final TextureRegion whitePixel, - Skin skin, float minRadius, + public PieMenu(final TextureRegion whitePixel, + Skin skin, float preferredRadius, float innerRadiusPercent, float startDegreesOffset, float totalDegreesDrawn) { - super(batch, whitePixel, minRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); + super(whitePixel, preferredRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); setStyle(skin.get(PieMenuStyle.class)); } /** * See {@link PieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. * @param style the name of the style to be extracted from the skin. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @param preferredRadius the {@link #preferredRadius} that defines the + * size of the widget. */ - public PieMenu(final Batch batch, final TextureRegion whitePixel, - Skin skin, String style, float minRadius) { - super(batch, whitePixel, minRadius); + public PieMenu(final TextureRegion whitePixel, + Skin skin, String style, float preferredRadius) { + super(whitePixel, preferredRadius); setStyle(skin.get(style, PieMenuStyle.class)); } /** * See {@link PieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. * @param style the name of the style to be extracted from the skin. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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 PieMenu(final Batch batch, final TextureRegion whitePixel, - Skin skin, String style, float minRadius, + public PieMenu(final TextureRegion whitePixel, + Skin skin, String style, float preferredRadius, float innerRadiusPercent) { - super(batch, whitePixel, minRadius, innerRadiusPercent); + super(whitePixel, preferredRadius, innerRadiusPercent); setStyle(skin.get(style, PieMenuStyle.class)); } /** * See {@link PieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. * @param style the name of the style to be extracted from the skin. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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 PieMenu(final Batch batch, final TextureRegion whitePixel, - Skin skin, String style, float minRadius, + public PieMenu(final TextureRegion whitePixel, + Skin skin, String style, float preferredRadius, float innerRadiusPercent, float startDegreesOffset) { - super(batch, whitePixel, minRadius, innerRadiusPercent, startDegreesOffset); + super(whitePixel, preferredRadius, innerRadiusPercent, startDegreesOffset); setStyle(skin.get(style, PieMenuStyle.class)); } /** * See {@link PieMenu} for a description. * - * @param batch used to draw everything but the contained actors. * @param whitePixel a 1x1 white pixel. * @param skin defines the way the widget looks like. * @param style the name of the style to be extracted from the skin. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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. @@ -330,10 +330,10 @@ public PieMenu(final Batch batch, final TextureRegion whitePixel, * many degrees the widget will span, starting from * its {@link #startDegreesOffset}. */ - public PieMenu(final Batch batch, final TextureRegion whitePixel, - Skin skin, String style, float minRadius, + public PieMenu(final TextureRegion whitePixel, + Skin skin, String style, float preferredRadius, float innerRadiusPercent, float startDegreesOffset, float totalDegreesDrawn) { - super(batch, whitePixel, minRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); + super(whitePixel, preferredRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); setStyle(skin.get(style, PieMenuStyle.class)); } @@ -389,21 +389,6 @@ public int findChildIndexAtStage(float x, float y) { : getAmountOfChildren(); // "getAmountOfChildren" is equivalent to "invalid" } - /** - * Checks whether or not the input coordinate is within (exclusively) - * the inner-radius. - * - * @param x x-coordinate relative to the center of the widget's - * @param y y-coordinate relative to the center of the widget's - * @return 'true' only if the coordinates fall within the widget's - * inner radius. - */ - public boolean isWithinInnerRadius(float x, float y) { - float distance = pow2(x) + pow2(y); - float innerRadSquared = pow2(getInnerRadiusLength()); - return distance < innerRadSquared; - } - /** * Used to transform an index into a known range: it'll either remain itself * if it was designating a valid child index, else it becomes the @@ -416,40 +401,6 @@ public int mapIndex(int index) { return isValidIndex(index) ? index : defaultIndex; } - /** - * @param x x-coordinate relative to the origin (bottom left) of the widget - * @param y y-coordinate relative to the origin (bottom left) of the widget - * @param touchable if {@code true}, hit detection will respect the - * {@link #setTouchable(Touchable) touchability}. - * @return deepest child's hit at (x,y). Else, the widget itself if it's - * the background. Else the widget itself if with infinite range. - * Else null. - */ - @Override - public Actor hit(float x, float y, boolean touchable) { - if (touchable && getTouchable() == Touchable.disabled) return null; - if (!isVisible()) return null; - - localToStageCoordinates(vector2.set(x,y)); - int childIndex = findChildIndexAtStage(vector2.x,vector2.y); - if (isValidIndex(childIndex)) { - Actor child = getChildren().get(childIndex); - if(child.getTouchable() == Touchable.disabled) - return this; - child.parentToLocalCoordinates(vector2.set(x, y)); - Actor hit = child.hit(vector2.x, vector2.y, touchable); - if(hit != null) - return hit; - else - return this; - } - - if(infiniteSelectionRange) - return this; - - return null; - } - @Override public Color getColor(int index) { if(style.hoverSelectedColor != null @@ -536,7 +487,7 @@ protected void checkStyle(PieMenuStyle style) { * Encompasses the characteristics that define the style of the Widget * to be drawn. */ - public static class PieMenuStyle extends RadialGroupStyle { + public static class PieMenuStyle extends PieWidgetStyle { /** * Recommended. Optional.
diff --git a/src/main/java/com/payne/games/piemenu/PieWidget.java b/src/main/java/com/payne/games/piemenu/PieWidget.java new file mode 100644 index 0000000..8581756 --- /dev/null +++ b/src/main/java/com/payne/games/piemenu/PieWidget.java @@ -0,0 +1,736 @@ +package com.payne.games.piemenu; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup; +import com.badlogic.gdx.scenes.scene2d.utils.Drawable; +import com.badlogic.gdx.scenes.scene2d.utils.TransformDrawable; +import com.badlogic.gdx.utils.Align; +import space.earlygrey.shapedrawer.ShapeDrawer; + + +/** + * 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}. + * + * @author Jérémi Grenier-Berthiaume (aka "payne") + */ +public class PieWidget extends RadialGroup { + + + /** + * Defines the way the widget looks. + */ + private PieWidgetStyle style; + + /** + * Used to draw on the screen many elements of the style. + */ + protected ShapeDrawer sd; + + /** + * The white pixel used to initialized a {@link ShapeDrawer}. + */ + protected TextureRegion whitePixel; + + + /* For internal use (optimization). */ + protected static final Color TRANSPARENT = new Color(0,0,0,0); + private static Vector2 vector2 = new Vector2(); + private static Vector2 vector22 = new Vector2(); + private static Vector2 vector23 = new Vector2(); + + + + + + + /** Used internally for the shared properties among constructors of RadialWidgets. */ + protected void constructorsCommon(TextureRegion whitePixel) { + this.whitePixel = whitePixel; + } + + /** Used internally for the shared properties among constructors of RadialWidgets. */ + protected PieWidget(final TextureRegion whitePixel, float preferredRadius) { + super(preferredRadius); + constructorsCommon(whitePixel); + } + + /** Used internally for the shared properties among constructors of RadialWidgets. */ + protected PieWidget(final TextureRegion whitePixel, + float preferredRadius, float innerRadiusPercent) { + super(preferredRadius, innerRadiusPercent); + constructorsCommon(whitePixel); + } + + /** Used internally for the shared properties among constructors of RadialWidgets. */ + protected PieWidget(final TextureRegion whitePixel, + float preferredRadius, float innerRadiusPercent, float startDegreesOffset) { + super(preferredRadius, innerRadiusPercent, startDegreesOffset); + constructorsCommon(whitePixel); + } + + /** Used internally for the shared properties among constructors of RadialWidgets. */ + protected PieWidget(final TextureRegion whitePixel, + float preferredRadius, float innerRadiusPercent, + float startDegreesOffset, float totalDegreesDrawn) { + super(preferredRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); + constructorsCommon(whitePixel); + } + + /** + * See {@link PieWidget} for a description. + * + * @param whitePixel a 1x1 white pixel. + * @param style defines the way the widget looks like. + * @param preferredRadius the {@link #preferredRadius} that defines the + * size of the widget. + */ + public PieWidget(final TextureRegion whitePixel, + PieWidgetStyle style, float preferredRadius) { + this(whitePixel, preferredRadius); + setStyle(style); + } + + /** + * See {@link PieWidget} for a description. + * + * @param whitePixel a 1x1 white pixel. + * @param style defines the way the widget looks like. + * @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 PieWidget(final TextureRegion whitePixel, + PieWidgetStyle style, float preferredRadius, + float innerRadiusPercent) { + this(whitePixel, preferredRadius, innerRadiusPercent); + setStyle(style); + } + + /** + * See {@link PieWidget} for a description. + * + * @param whitePixel a 1x1 white pixel. + * @param style defines the way the widget looks like. + * @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 PieWidget(final TextureRegion whitePixel, + PieWidgetStyle style, float preferredRadius, + float innerRadiusPercent, float startDegreesOffset) { + this(whitePixel, preferredRadius, innerRadiusPercent, startDegreesOffset); + setStyle(style); + } + + /** + * See {@link PieWidget} for a description. + * + * @param whitePixel a 1x1 white pixel. + * @param style defines the way the widget looks like. + * @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 PieWidget(final TextureRegion whitePixel, + PieWidgetStyle style, float preferredRadius, + float innerRadiusPercent, float startDegreesOffset, float totalDegreesDrawn) { + this(whitePixel, preferredRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); + setStyle(style); + } + + /** + * See {@link PieWidget} for a description. + * + * @param whitePixel a 1x1 white pixel. + * @param skin defines the way the widget looks like. + * @param preferredRadius the {@link #preferredRadius} that defines the + * size of the widget. + */ + public PieWidget(final TextureRegion whitePixel, + Skin skin, float preferredRadius) { + this(whitePixel, preferredRadius); + setStyle(skin.get(PieWidgetStyle.class)); + } + + /** + * See {@link PieWidget} for a description. + * + * @param whitePixel a 1x1 white pixel. + * @param skin defines the way the widget looks like. + * @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 PieWidget(final TextureRegion whitePixel, + Skin skin, float preferredRadius, + float innerRadiusPercent) { + this(whitePixel, preferredRadius, innerRadiusPercent); + setStyle(skin.get(PieWidgetStyle.class)); + } + + /** + * See {@link PieWidget} for a description. + * + * @param whitePixel a 1x1 white pixel. + * @param skin defines the way the widget looks like. + * @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 PieWidget(final TextureRegion whitePixel, + Skin skin, float preferredRadius, + float innerRadiusPercent, float startDegreesOffset) { + this(whitePixel, preferredRadius, innerRadiusPercent, startDegreesOffset); + setStyle(skin.get(PieWidgetStyle.class)); + } + + /** + * See {@link PieWidget} for a description. + * + * @param whitePixel a 1x1 white pixel. + * @param skin defines the way the widget looks like. + * @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 PieWidget(final TextureRegion whitePixel, + Skin skin, float preferredRadius, + float innerRadiusPercent, float startDegreesOffset, float totalDegreesDrawn) { + this(whitePixel, preferredRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); + setStyle(skin.get(PieWidgetStyle.class)); + } + + /** + * See {@link PieWidget} for a description. + * + * @param whitePixel a 1x1 white pixel. + * @param skin defines the way the widget looks like. + * @param style the name of the style to be extracted from the skin. + * @param preferredRadius the {@link #preferredRadius} that defines the + * size of the widget. + */ + public PieWidget(final TextureRegion whitePixel, + Skin skin, String style, float preferredRadius) { + this(whitePixel, preferredRadius); + setStyle(skin.get(style, PieWidgetStyle.class)); + } + + + /** + * See {@link PieWidget} for a description. + * + * @param whitePixel a 1x1 white pixel. + * @param skin defines the way the widget looks like. + * @param style the name of the style to be extracted from the skin. + * @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 PieWidget(final TextureRegion whitePixel, + Skin skin, String style, float preferredRadius, + float innerRadiusPercent) { + this(whitePixel, preferredRadius, innerRadiusPercent); + setStyle(skin.get(style, PieWidgetStyle.class)); + } + + /** + * See {@link PieWidget} for a description. + * + * @param whitePixel a 1x1 white pixel. + * @param skin defines the way the widget looks like. + * @param style the name of the style to be extracted from the skin. + * @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 PieWidget(final TextureRegion whitePixel, + Skin skin, String style, float preferredRadius, + float innerRadiusPercent, float startDegreesOffset) { + this(whitePixel, preferredRadius, innerRadiusPercent, startDegreesOffset); + setStyle(skin.get(style, PieWidgetStyle.class)); + } + + /** + * See {@link PieWidget} for a description. + * + * @param whitePixel a 1x1 white pixel. + * @param skin defines the way the widget looks like. + * @param style the name of the style to be extracted from the skin. + * @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 PieWidget(final TextureRegion whitePixel, + Skin skin, String style, float preferredRadius, + float innerRadiusPercent, float startDegreesOffset, float totalDegreesDrawn) { + this(whitePixel, preferredRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); + setStyle(skin.get(style, PieWidgetStyle.class)); + } + + + + + + + + + /** + * Ensures the {@link ShapeDrawer}'s {@link Batch} matches the one that is currently + * trying to draw the widget. + * + * @param batch the batch that is being used to draw the widget. + * @return {@code false} only if the batch used is {@code null}. {@code true} otherwise. + */ + public boolean updateShapeDrawer(Batch batch) { + if (batch == null) // todo: can this happen? + return false; + + if (sd == null || sd.getBatch() == null) { + sd = new ShapeDrawer(batch, whitePixel) { + /* OPTIONAL: Ensuring a certain smoothness. */ + @Override + protected int estimateSidesRequired(float radiusX, float radiusY) { + return 200; + } + }; + return true; + } + + if (sd.getBatch() == batch) + return true; + + sd = new ShapeDrawer(batch, whitePixel) { + /* OPTIONAL: Ensuring a certain smoothness. */ + @Override + protected int estimateSidesRequired(float radiusX, float radiusY) { + return 200; + } + }; + return true; + } + + @Override + public boolean isBackgroundHit(float x, float y) { + if(style.background == null && style.backgroundColor == null) + return false; + return isWithinInnerRadius(x - getWidth()/2, y - getHeight()/2); + } + + @Override + public void draw(Batch batch, float parentAlpha) { + drawWithShapeDrawer(batch, parentAlpha, totalDegreesDrawn); + drawMe(batch, parentAlpha); + } + + /** Calls the {@link WidgetGroup#draw(Batch, float)} method. */ + protected void drawMe(Batch batch, float parentAlpha) { + super.draw(batch, parentAlpha); + } + + /** + * Used to propagate the parent's alpha value to the children.
+ * Changes the {@link ShapeDrawer}'s color. + * + * @param sd the {@link ShapeDrawer} whose color will be changed. + * @param input the {@link Color} to be copying RGB values from. + */ + protected void propagateAlpha(ShapeDrawer sd, Color input) { + sd.setColor(input.r, input.g, input.b, input.a * globalAlphaMultiplier); + } + + /** + * Takes care of drawing everything that {@link #layout()} didn't. + * (Basically everything but the children Actors.) + * + * @param batch a Batch used to draw Drawables. The {@link #sd} is used to + * draw everything else. + * @param parentAlpha the inherited parent alpha. + * @param degreesToDraw how many degrees from the offset should be drawn. + */ + protected void drawWithShapeDrawer(Batch batch, float parentAlpha, float degreesToDraw) { + + /* Ensure the ShapeDrawer uses the proper Batch to draw. */ + if(!updateShapeDrawer(batch)) + return; + + /* Pre-calculating */ + float bgRadian = MathUtils.degreesToRadians*degreesToDraw; + float tmpOffset = MathUtils.degreesToRadians*(startDegreesOffset + getRotation()); + final int SIZE = getAmountOfChildren(); + float tmpRad = bgRadian / SIZE; + + /* Background image */ + if(style.background != null) { + Color bc = batch.getColor(); + float restoreAlpha = bc.a; + batch.setColor(bc.r, bc.g, bc.b, bc.a * globalAlphaMultiplier); + if(style.background instanceof TransformDrawable) { + ((TransformDrawable)(style.background)).draw(batch, + getX(Align.center) - getCurrentRadius(), + getY(Align.center) - getCurrentRadius(), + getCurrentRadius(), getCurrentRadius(), + getCurrentDiameter(), getCurrentDiameter(), + getScaleX(), getScaleY(), + getRotation()); + } else { + style.background.draw(batch, + getX(Align.center) - getCurrentRadius(), + getY(Align.center) - getCurrentRadius(), + getCurrentDiameter(), getCurrentDiameter()); + } + batch.setColor(bc.r, bc.g, bc.b, restoreAlpha); + } + + /* Rest of background */ + if(style.backgroundColor != null) { + propagateAlpha(sd, style.backgroundColor); + sd.sector(getX(Align.center), getY(Align.center), + getCurrentRadius()-BUFFER, tmpOffset, bgRadian); // buffer to prevent bg from sticking out from below children + } + + /* Children */ + vector2.set(getX(Align.center), getY(Align.center)); + for(int i=0; i 0) { + propagateAlpha(sd, style.separatorColor); + sd.line(pointAtAngle(vector22, vector2, getInnerRadiusLength(), drawnRadianAngle), + pointAtAngle(vector23, vector2, getCurrentRadius(), drawnRadianAngle), + style.separatorWidth); + } + } + + /** + * To get the coordinates of a point along a line traced from the center, + * along the designated angle, at the designated distance from the center. + * + * @param center center point of the Circle + * @param radius how far from the center the desired point is + * @param radian the angle along which the line is calculated + * @return the point associated with those parameters + */ + public Vector2 pointAtAngle(Vector2 output, Vector2 center, float radius, float radian) { + output.set(center.x + radius * MathUtils.cos(radian), center.y + radius * MathUtils.sin(radian)); + return output; + } + + /** + * Determines the color of the slice in which resides the Actor designated + * by the {@code index} parameter. By default, the colors come from the way + * you have set up your Style (anything that extends {@link PieWidgetStyle}).
+ * Override this method when creating your Widget if you want to have control + * over those colors.
+ * Do not set the color of the {@link ShapeDrawer} in there: that is + * handled internally. Just return the desired Color.

+ * Here is an example: + *
+     * {@code
+     * RadialGroup myWidget = new RadialGroup(shapeDrawer, myStyle, 77) {
+     *     public Color getColor(int index) {
+     *         Color fader = super.getColor(index);
+     *         // This will fade the slices' alpha value
+     *         return new Color(fader.r, fader.g, fader.b, fader.a/index);
+     *     }
+     * };
+     * }
+     * 
+ * + * @param index index of the child whose slice is to be drawn with the returned Color. + * @return the Color to be used to draw the slice of the child with the given index. + */ + public Color getColor(int index) { + if(style.alternateSliceColor != null + && index%2 == 1) + return style.alternateSliceColor; + + if(style.sliceColor != null) + return style.sliceColor; + + return TRANSPARENT; + } + + protected void drawChild(Vector2 vector2, int index, float startAngle, float radian) { + propagateAlpha(sd, getColor(index)); + sd.arc(vector2.x, vector2.y, (getCurrentRadius()+ getInnerRadiusLength())/2, + startAngle, radian, getCurrentRadius()- getInnerRadiusLength()); + + /* Circumferences */ + drawChildCircumference(vector2, startAngle, radian, getCurrentRadius() - style.circumferenceWidth/2); + if(innerRadiusPercent > 0) + drawChildCircumference(vector2, startAngle, radian, getInnerRadiusLength() + style.circumferenceWidth/2); + } + + protected void drawChildCircumference(Vector2 vector2, float startAngle, float radian, float radius) { + if(style.circumferenceColor != null && style.circumferenceWidth > 0) { + propagateAlpha(sd, style.circumferenceColor); + sd.arc(vector2.x, vector2.y, radius, startAngle, radian, style.circumferenceWidth); + } + } + + + + + + + + + + + + + /* + =================================== STYLE ================================== + */ + + + /** + * Returns the label's style. Modifying the returned style may not have an + * effect until {@link #setStyle(PieWidgetStyle)} is called.
+ * It's probable that your code will look like this (to give you an idea): + *
+     * {@code
+     * radialGroup.getStyle().whatYouWantToChange = someNewValue;
+     * radialGroup.setStyle(radialGroup.getStyle());
+     * }
+     * 
+ * + * @return the Style that defines this Widget. This style contains information + * about what is the value of the radius or the width of the separators, for + * example. + */ + public PieWidgetStyle getStyle() { + return style; + } + + + /** + * Runs checks before assigning the style to the Widget. Only a valid style + * will pass the test. + * + * @param style the style that will be checked before being assigned. + */ + public void setStyle(PieWidgetStyle style) { + checkStyle(style); + this.style = style; + invalidate(); + } + + /** + * Ensures the input values for the given style are valid. + * + * @param style a style class you want to check properties of. + */ + protected void checkStyle(PieWidgetStyle style) { + if(style == null) + throw new IllegalArgumentException("style cannot be null."); + + if(style.separatorWidth < 0) + throw new IllegalArgumentException("separatorWidth cannot be negative."); + + if(style.circumferenceWidth < 0) + throw new IllegalArgumentException("circumferenceWidth cannot be negative."); + + if(style.sliceColor == null && style.alternateSliceColor != null) + throw new IllegalArgumentException("sliceColor must also be specified if you are defining alternateSliceColor. " + + "You can however only specify the sliceColor, if you want."); + } + + /** + * Encompasses the characteristics that define the style of the Widget + * to be drawn. + */ + public static class PieWidgetStyle { + + /** + * Recommended. Optional.
+ * A background that will be drawn behind everything else within the Widget.
+ * Be mindful of the fact that this is unaffected by any of the other + * variables: it will be resized to fit in the whole region that + * represents the position, width and height of the widget. + */ + public Drawable background; + + /** + * Optional.
+ * A background color that, if provided, will be drawn over the + * background image and below everything else.
+ * It mostly acts as a quick set up option if you do not have an image + * for you background. + */ + public Color backgroundColor; + + /** + * Recommended. Optional.
+ * The color used by the separating lines between each item.
+ * It is recommended mostly for the case where you are not defining an + * {@link #alternateSliceColor}.
+ * If you do not define a {@link #separatorWidth} along with this value, + * no lines will be visible. + */ + public Color separatorColor; + + /** + * Recommended. Optional.
+ * The color used to fill the "pie sectors" (i.e. slice) of each item.
+ * Consider using a fairly low alpha value if you are providing a + * {@link #background} {@link Drawable}. + */ + public Color sliceColor; + + /** + * Optional.
+ * If this color is set, the "pie sectors" will alternate between the + * {@link #sliceColor} and this one so that their defining region + * is more easily distinguished. + */ + public Color alternateSliceColor; + + /** + * Optional.
+ * The color used for the line that defines the circumference of the + * Widget. If the Widget is not a complete a circle, this will only be + * applied along the partial circumference.
+ * If you have set a non-zero {@link #innerRadiusPercent} value, this will + * also apply to the "inner radius" of your Widget.
+ * If you do not define a {@link #circumferenceWidth} along with this + * value, no circumference will be visible. + */ + public Color circumferenceColor; + + /** + * Recommended. Optional.
+ * Determines how wide the lines that separate each slice will be.
+ * If no {@link #separatorColor} was provided along with this value, + * no lines will be drawn. + */ + public float separatorWidth; + + /** + * Optional.
+ * Determines how wide the circumference line will be.
+ * If no {@link #circumferenceColor} was provided along with this value, + * no circumference will be drawn. + */ + public float circumferenceWidth; + + + /** + * Encompasses the characteristics that define the style of the Widget + * to be drawn. + */ + public PieWidgetStyle() { + } + + /** + * Encompasses the characteristics that define the style of the Widget + * to be drawn. + * + * @param style a Style to copy the parameters from. + */ + public PieWidgetStyle(PieWidgetStyle style) { + this.background = style.background; + this.circumferenceWidth = style.circumferenceWidth; + this.circumferenceColor = new Color(style.circumferenceColor); + this.separatorWidth = style.separatorWidth; + this.separatorColor = new Color(style.separatorColor); + this.sliceColor = new Color(style.sliceColor); + this.alternateSliceColor = new Color(style.alternateSliceColor); + this.backgroundColor = new Color(style.backgroundColor); + } + } + + + + + + + + + + /* + =============================== GETTERS/SETTERS ============================ + */ + + + /** + * @return the ShapeDrawer used to draw everything but the contained Actors. + */ + public ShapeDrawer getShapeDrawer() { + return sd; + } + + /** + * You probably shouldn't be messing with this, but it's provided for + * convenience reasons.
+ * For example, it's possible that your widget will be so big that + * the {@link ShapeDrawer} will crash with an Exception while trying to + * draw it. You would then want to use this setter to provide a brand new + * instance which didn't override the {@code estimateSidesRequired(float, float)} + * method to try to increase the smoothness of the curves. + * + * @param sd the new instance of {@link ShapeDrawer} that you want to use. + */ + public void setShapeDrawer(ShapeDrawer sd) { + this.sd = sd; + } +} diff --git a/src/main/java/com/payne/games/piemenu/RadialGroup.java b/src/main/java/com/payne/games/piemenu/RadialGroup.java index b770694..a954e5f 100644 --- a/src/main/java/com/payne/games/piemenu/RadialGroup.java +++ b/src/main/java/com/payne/games/piemenu/RadialGroup.java @@ -1,58 +1,45 @@ package com.payne.games.piemenu; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.Group; import com.badlogic.gdx.scenes.scene2d.Touchable; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup; -import com.badlogic.gdx.scenes.scene2d.utils.Drawable; -import com.badlogic.gdx.scenes.scene2d.utils.TransformDrawable; import com.badlogic.gdx.utils.Align; +import com.payne.games.piemenu.PieWidget.PieWidgetStyle; import space.earlygrey.shapedrawer.ShapeDrawer; /** * A RadialGroup aims at providing the user with a simple way to lay out - * the contained Actors in a circular fashion. + * the contained Actors in a circular fashion. It does not use a + * {@link ShapeDrawer} in any way. Thus, no Style whatsoever is required. * * @author Jérémi Grenier-Berthiaume (aka "payne") */ public class RadialGroup extends WidgetGroup { - /** - * Used to draw on the screen many elements of the style. - */ - protected ShapeDrawer sd; - - /** - * Defines the way the widget looks. - */ - private RadialGroupStyle style; - /** * Required.
* The radius that defines how big the Widget will be (in terms of scene2d, * this is actually half the "minimal size" this widget will ever take).
* It must be bigger than {@value #BUFFER}. */ - protected float minRadius; + protected float preferredRadius; /** * Optional.
- * If provided, the {@link RadialGroupStyle#sliceColor} will only fill - * the region defined between the {@link #minRadius} and its percentage + * If provided, the {@link PieWidgetStyle#sliceColor} will only fill + * the region defined between the {@link #preferredRadius} and its percentage * value coming from this.
- * For example, having a {@link #minRadius} of 80 and a + * For example, having a {@link #preferredRadius} of 80 and a * {@link #innerRadiusPercent} of 0.5 will mean that the inner-radius will * stand at 40 pixels from the center.
* A hole will be left into the middle of the Widget, like a doughnut, and - * if a {@link RadialGroupStyle#background} or a - * {@link RadialGroupStyle#backgroundColor} was provided, it will be visible + * if a {@link PieWidgetStyle#background} or a + * {@link PieWidgetStyle#backgroundColor} was provided, it will be visible * in the middle.
* Actors inserted into the Widget are by default placed in the middle * between the inner-radius and the radius. @@ -94,277 +81,63 @@ public class RadialGroup extends WidgetGroup { /* For internal use (optimization). */ private float lastRadius = 0; protected static final float BUFFER = 1; - protected static final Color TRANSPARENT = new Color(0,0,0,0); private static Vector2 vector2 = new Vector2(); - private static Vector2 vector22 = new Vector2(); - private static Vector2 vector23 = new Vector2(); - - - + /** Used internally for the shared properties among constructors of RadialWidgets. */ protected void constructorsCommon() { setTouchable(Touchable.childrenOnly); } - /** - * Used internally for the shared properties among constructors of RadialWidgets. - */ - protected RadialGroup(final Batch batch, final TextureRegion whitePixel, float minRadius) { - this.sd = new ShapeDrawer(batch, whitePixel) { - /* OPTIONAL: Ensuring a certain smoothness. */ - @Override - protected int estimateSidesRequired(float radiusX, float radiusY) { - return 200; - } - }; - setMinRadius(minRadius); - constructorsCommon(); - } - - /** - * Used internally for the shared properties among constructors of RadialWidgets. - */ - protected RadialGroup(final Batch batch, final TextureRegion whitePixel, - float minRadius, float innerRadiusPercent) { - this(batch, whitePixel, minRadius); - setInnerRadiusPercent(innerRadiusPercent); - } - - /** - * Used internally for the shared properties among constructors of RadialWidgets. - */ - protected RadialGroup(final Batch batch, final TextureRegion whitePixel, - float minRadius, float innerRadiusPercent, float startDegreesOffset) { - this(batch, whitePixel, minRadius, innerRadiusPercent); - setStartDegreesOffset(startDegreesOffset); - } - - /** - * Used internally for the shared properties among constructors of RadialWidgets. - */ - protected RadialGroup(final Batch batch, final TextureRegion whitePixel, - float minRadius, float innerRadiusPercent, - float startDegreesOffset, float totalDegreesDrawn) { - this(batch, whitePixel, minRadius, innerRadiusPercent, startDegreesOffset); - setTotalDegreesDrawn(totalDegreesDrawn); - } - - /** - * See {@link RadialGroup} for a description. - * - * @param batch used to draw everything but the contained actors. - * @param whitePixel a 1x1 white pixel. - * @param style defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. - */ - public RadialGroup(final Batch batch, final TextureRegion whitePixel, - RadialGroupStyle style, float minRadius) { - this(batch, whitePixel, minRadius); - setStyle(style); - } - - /** - * See {@link RadialGroup} for a description. - * - * @param batch used to draw everything but the contained actors. - * @param whitePixel a 1x1 white pixel. - * @param style defines the way the widget looks like. - * @param minRadius the {@link #minRadius} 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 RadialGroup(final Batch batch, final TextureRegion whitePixel, - RadialGroupStyle style, float minRadius, - float innerRadiusPercent) { - this(batch, whitePixel, minRadius, innerRadiusPercent); - setStyle(style); - } /** * See {@link RadialGroup} for a description. * - * @param batch used to draw everything but the contained actors. - * @param whitePixel a 1x1 white pixel. - * @param style defines the way the widget looks like. - * @param minRadius the {@link #minRadius} 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 preferredRadius the {@link #preferredRadius} that defines the + * size of the widget. */ - public RadialGroup(final Batch batch, final TextureRegion whitePixel, - RadialGroupStyle style, float minRadius, - float innerRadiusPercent, float startDegreesOffset) { - this(batch, whitePixel, minRadius, innerRadiusPercent, startDegreesOffset); - setStyle(style); - } - - /** - * See {@link RadialGroup} for a description. - * - * @param batch used to draw everything but the contained actors. - * @param whitePixel a 1x1 white pixel. - * @param style defines the way the widget looks like. - * @param minRadius the {@link #minRadius} 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 RadialGroup(final Batch batch, final TextureRegion whitePixel, - RadialGroupStyle style, float minRadius, - float innerRadiusPercent, float startDegreesOffset, float totalDegreesDrawn) { - this(batch, whitePixel, minRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); - setStyle(style); - } - - /** - * See {@link RadialGroup} for a description. - * - * @param batch used to draw everything but the contained actors. - * @param whitePixel a 1x1 white pixel. - * @param skin defines the way the widget looks like. - * @param minRadius the {@link #minRadius} that defines the size of the widget. - */ - public RadialGroup(final Batch batch, final TextureRegion whitePixel, - Skin skin, float minRadius) { - this(batch, whitePixel, minRadius); - setStyle(skin.get(RadialGroupStyle.class)); - } - - /** - * See {@link RadialGroup} for a description. - * - * @param batch used to draw everything but the contained actors. - * @param whitePixel a 1x1 white pixel. - * @param skin defines the way the widget looks like. - * @param minRadius the {@link #minRadius} 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 RadialGroup(final Batch batch, final TextureRegion whitePixel, - Skin skin, float minRadius, - float innerRadiusPercent) { - this(batch, whitePixel, minRadius, innerRadiusPercent); - setStyle(skin.get(RadialGroupStyle.class)); - } - - /** - * See {@link RadialGroup} for a description. - * - * @param batch used to draw everything but the contained actors. - * @param whitePixel a 1x1 white pixel. - * @param skin defines the way the widget looks like. - * @param minRadius the {@link #minRadius} 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 RadialGroup(final Batch batch, final TextureRegion whitePixel, - Skin skin, float minRadius, - float innerRadiusPercent, float startDegreesOffset) { - this(batch, whitePixel, minRadius, innerRadiusPercent, startDegreesOffset); - setStyle(skin.get(RadialGroupStyle.class)); - } - - /** - * See {@link RadialGroup} for a description. - * - * @param batch used to draw everything but the contained actors. - * @param whitePixel a 1x1 white pixel. - * @param skin defines the way the widget looks like. - * @param minRadius the {@link #minRadius} 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 RadialGroup(final Batch batch, final TextureRegion whitePixel, - Skin skin, float minRadius, - float innerRadiusPercent, float startDegreesOffset, float totalDegreesDrawn) { - this(batch, whitePixel, minRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); - setStyle(skin.get(RadialGroupStyle.class)); - } - - /** - * See {@link RadialGroup} for a description. - * - * @param batch used to draw everything but the contained actors. - * @param whitePixel a 1x1 white pixel. - * @param skin defines the way the widget looks like. - * @param style the name of the style to be extracted from the skin. - * @param minRadius the {@link #minRadius} that defines the size of the widget. - */ - public RadialGroup(final Batch batch, final TextureRegion whitePixel, - Skin skin, String style, float minRadius) { - this(batch, whitePixel, minRadius); - setStyle(skin.get(style, RadialGroupStyle.class)); + public RadialGroup(float preferredRadius) { + setPreferredRadius(preferredRadius); + constructorsCommon(); } - /** * See {@link RadialGroup} for a description. * - * @param batch used to draw everything but the contained actors. - * @param whitePixel a 1x1 white pixel. - * @param skin defines the way the widget looks like. - * @param style the name of the style to be extracted from the skin. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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 RadialGroup(final Batch batch, final TextureRegion whitePixel, - Skin skin, String style, float minRadius, - float innerRadiusPercent) { - this(batch, whitePixel, minRadius, innerRadiusPercent); - setStyle(skin.get(style, RadialGroupStyle.class)); + public RadialGroup(float preferredRadius, float innerRadiusPercent) { + this(preferredRadius); + setInnerRadiusPercent(innerRadiusPercent); } /** * See {@link RadialGroup} for a description. * - * @param batch used to draw everything but the contained actors. - * @param whitePixel a 1x1 white pixel. - * @param skin defines the way the widget looks like. - * @param style the name of the style to be extracted from the skin. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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 RadialGroup(final Batch batch, final TextureRegion whitePixel, - Skin skin, String style, float minRadius, - float innerRadiusPercent, float startDegreesOffset) { - this(batch, whitePixel, minRadius, innerRadiusPercent, startDegreesOffset); - setStyle(skin.get(style, RadialGroupStyle.class)); + public RadialGroup(float preferredRadius, float innerRadiusPercent, + float startDegreesOffset) { + this(preferredRadius, innerRadiusPercent); + setStartDegreesOffset(startDegreesOffset); } /** * See {@link RadialGroup} for a description. * - * @param batch used to draw everything but the contained actors. - * @param whitePixel a 1x1 white pixel. - * @param skin defines the way the widget looks like. - * @param style the name of the style to be extracted from the skin. - * @param minRadius the {@link #minRadius} that defines the size of the widget. + * @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. @@ -374,11 +147,10 @@ public RadialGroup(final Batch batch, final TextureRegion whitePixel, * many degrees the widget will span, starting from * its {@link #startDegreesOffset}. */ - public RadialGroup(final Batch batch, final TextureRegion whitePixel, - Skin skin, String style, float minRadius, - float innerRadiusPercent, float startDegreesOffset, float totalDegreesDrawn) { - this(batch, whitePixel, minRadius, innerRadiusPercent, startDegreesOffset, totalDegreesDrawn); - setStyle(skin.get(style, RadialGroupStyle.class)); + public RadialGroup(float preferredRadius, float innerRadiusPercent, + float startDegreesOffset, float totalDegreesDrawn) { + this(preferredRadius, innerRadiusPercent, startDegreesOffset); + setTotalDegreesDrawn(totalDegreesDrawn); } @@ -390,50 +162,49 @@ public RadialGroup(final Batch batch, final TextureRegion whitePixel, - - /** * The current diameter of the widget.
- * This might not be twice the {@link #minRadius}. + * This might not be twice the {@link #preferredRadius}. * * @return {@code Math.min(getWidth(), getHeight())} */ - protected float getMaxDiameter() { + protected float getCurrentDiameter() { return Math.min(getWidth(), getHeight()); } /** * The current radius of the widget.
- * This might not be {@link #minRadius}. + * This might not be {@link #preferredRadius}. * * @return {@code Math.min(getWidth(), getHeight()) / 2} */ - protected float getMaxRadius() { - return getMaxDiameter()/2; + protected float getCurrentRadius() { + return getCurrentDiameter()/2; } @Override public float getPrefWidth() { - return getMaxDiameter(); + return getCurrentDiameter(); } @Override public float getPrefHeight() { - return getMaxDiameter(); + return getCurrentDiameter(); } @Override public float getMinWidth() { - return minRadius * 2; + return preferredRadius * 2; } @Override public float getMinHeight() { - return minRadius * 2; + return preferredRadius * 2; } @Override public void addActor(Actor actor) { + // todo: this might not need to be Overriden if(actor == null) throw new IllegalArgumentException("actor cannot be null."); super.addActor(actor); invalidate(); @@ -475,7 +246,7 @@ public boolean removeActor(Actor actor) { * @return distance of this Actor's center from the center of the widget. */ public float getActorDistanceFromCenter(Actor actor) { - return (getMaxRadius() + getInnerRadiusLength())/2; + return (getCurrentRadius() + getInnerRadiusLength())/2; } /** @@ -505,7 +276,7 @@ public float getActorDistanceFromCenter(Actor actor) { * positioned from the center of the widget. */ public void modifyActor(Actor actor, float degreesPerChild, float actorDistanceFromCenter) { - + // todo: possibly add a default resize-value for `Image` instances here? } /** @@ -534,7 +305,7 @@ public void modifyActor(Actor actor, float degreesPerChild, float actorDistanceF */ public float getEstimatedRadiusAt(float degreesPerChild, float actorDistanceFromCenter) { float tmp1 = actorDistanceFromCenter * MathUtils.sinDeg(degreesPerChild/2); - float tmp2 = getMaxRadius() - actorDistanceFromCenter; + float tmp2 = getCurrentRadius() - actorDistanceFromCenter; float tmp3 = actorDistanceFromCenter - getInnerRadiusLength(); return Math.min(Math.min(tmp1, tmp2), tmp3); } @@ -569,167 +340,9 @@ protected void updateOrigin() { setOrigin(getWidth()/2, getHeight()/2); // to support rotations around the center } - @Override - public void draw(Batch batch, float parentAlpha) { - drawWithShapeDrawer(batch, parentAlpha, totalDegreesDrawn); - drawMe(batch, parentAlpha); - } - - @Deprecated - protected void drawMe(Batch batch, float parentAlpha) { - super.draw(batch, parentAlpha); - } - - /** - * Used to propagate the parent's alpha value to the children.
- * Changes the {@link ShapeDrawer}'s color. - * - * @param sd the {@link ShapeDrawer} whose color will be changed. - * @param input the {@link Color} to be copying RGB values from. - */ - protected void propagateAlpha(ShapeDrawer sd, Color input) { - sd.setColor(input.r, input.g, input.b, input.a * globalAlphaMultiplier); - } - /** - * Takes care of drawing everything that {@link #layout()} didn't. - * (Basically everything but the children Actors.) - * - * @param batch a Batch used to draw Drawables. The {@link #sd} is used to - * draw everything else. - * @param parentAlpha the inherited parent alpha. - * @param degreesToDraw how many degrees from the offset should be drawn. - */ - protected void drawWithShapeDrawer(Batch batch, float parentAlpha, float degreesToDraw) { - - /* Pre-calculating */ - float bgRadian = MathUtils.degreesToRadians*degreesToDraw; - float tmpOffset = MathUtils.degreesToRadians*(startDegreesOffset + getRotation()); - final int SIZE = getAmountOfChildren(); - float tmpRad = bgRadian / SIZE; - - /* Background image */ - if(style.background != null) { - Color bc = batch.getColor(); - float restoreAlpha = bc.a; - batch.setColor(bc.r, bc.g, bc.b, bc.a * globalAlphaMultiplier); - if(style.background instanceof TransformDrawable) { - ((TransformDrawable)(style.background)).draw(batch, - getX(Align.center) - getMaxRadius(), getY(Align.center) - getMaxRadius(), - getMaxRadius(), getMaxRadius(), - getMaxDiameter(), getMaxDiameter(), - getScaleX(), getScaleY(), - getRotation()); - } else { - style.background.draw(batch, - getX(Align.center) - getMaxRadius(), - getY(Align.center) - getMaxRadius(), - getMaxDiameter(), getMaxDiameter()); - } - batch.setColor(bc.r, bc.g, bc.b, restoreAlpha); - } - - /* Rest of background */ - if(style.backgroundColor != null) { - propagateAlpha(sd, style.backgroundColor); - sd.sector(getX(Align.center), getY(Align.center), - getMaxRadius()-BUFFER, tmpOffset, bgRadian); // buffer to prevent bg from sticking out from below children - } - - /* Children */ - vector2.set(getX(Align.center), getY(Align.center)); - for(int i=0; i 0) { - propagateAlpha(sd, style.separatorColor); - sd.line(pointAtAngle(vector22, vector2, getInnerRadiusLength(), drawnRadianAngle), - pointAtAngle(vector23, vector2, getMaxRadius(), drawnRadianAngle), - style.separatorWidth); - } - } - - /** - * Determines the color of the slice in which resides the Actor designated - * by the {@code index} parameter. By default, the colors come from the way - * you have set up your Style (anything that extends {@link RadialGroupStyle}).
- * Override this method when creating your Widget if you want to have control - * over those colors.
- * Do not set the color of the {@link ShapeDrawer} in there: that is - * handled internally. Just return the desired Color.

- * Here is an example: - *
-     * {@code
-     * RadialGroup myWidget = new RadialGroup(shapeDrawer, myStyle, 77) {
-     *     public Color getColor(int index) {
-     *         Color fader = super.getColor(index);
-     *         // This will fade the slices' alpha value
-     *         return new Color(fader.r, fader.g, fader.b, fader.a/index);
-     *     }
-     * };
-     * }
-     * 
- * - * @param index index of the child whose slice is to be drawn with the returned Color. - * @return the Color to be used to draw the slice of the child with the given index. - */ - public Color getColor(int index) { - if(style.alternateSliceColor != null - && index%2 == 1) - return style.alternateSliceColor; - - if(style.sliceColor != null) - return style.sliceColor; - - return TRANSPARENT; - } - - protected void drawChild(Vector2 vector2, int index, float startAngle, float radian) { - propagateAlpha(sd, getColor(index)); - sd.arc(vector2.x, vector2.y, (getMaxRadius()+ getInnerRadiusLength())/2, - startAngle, radian, getMaxRadius()- getInnerRadiusLength()); - - /* Circumferences */ - drawChildCircumference(vector2, startAngle, radian, getMaxRadius() - style.circumferenceWidth/2); - if(innerRadiusPercent > 0) - drawChildCircumference(vector2, startAngle, radian, getInnerRadiusLength() + style.circumferenceWidth/2); - } - - protected void drawChildCircumference(Vector2 vector2, float startAngle, float radian, float radius) { - if(style.circumferenceColor != null && style.circumferenceWidth > 0) { - propagateAlpha(sd, style.circumferenceColor); - sd.arc(vector2.x, vector2.y, radius, startAngle, radian, style.circumferenceWidth); - } - } - - - /** - * To get the coordinates of a point along a line traced from the center, - * along the designated angle, at the designated distance from the center. - * - * @param center center point of the Circle - * @param radius how far from the center the desired point is - * @param radian the angle along which the line is calculated - * @return the point associated with those parameters - */ - public Vector2 pointAtAngle(Vector2 output, Vector2 center, float radius, float radian) { - output.set(center.x + radius * MathUtils.cos(radian), center.y + radius * MathUtils.sin(radian)); - return output; - } - - /** - * @param x x-coordinate relative to the origin (bottom left) of the widget - * @param y y-coordinate relative to the origin (bottom left) of the widget + * @param x x-coordinate relative to the bottom-left of the widget. + * @param y y-coordinate relative to the bottom-left of the widget. * @param touchable if {@code true}, hit detection will respect the * {@link #setTouchable(Touchable) touchability}. * @return deepest child's hit at (x,y). Else, the widget itself if it's @@ -740,23 +353,43 @@ public Actor hit(float x, float y, boolean touchable) { if (touchable && getTouchable() == Touchable.disabled) return null; if (!isVisible()) return null; - localToStageCoordinates(vector2.set(x,y)); - int childIndex = findChildIndexAtStage(vector2.x,vector2.y); - if (isValidIndex(childIndex)) { - Actor child = getChildren().get(childIndex); + /* Checking all children first to catch the ones extending beyond the widget. */ + for (Actor child : getChildren()) { if(child.getTouchable() == Touchable.disabled) - return this; - child.parentToLocalCoordinates(vector2.set(x, y)); + continue; + child.parentToLocalCoordinates(vector2.set(x,y)); Actor hit = child.hit(vector2.x, vector2.y, touchable); if(hit != null) return hit; - else - return this; } + /* Then we want to consider the widget's boundaries itself. */ + localToStageCoordinates(vector2.set(x,y)); + int childIndex = findChildIndexAtStage(vector2.x,vector2.y); + if(isValidIndex(childIndex)) + return this; + + /* And ultimately whether some background element is hit. */ + if(isBackgroundHit(x,y)) + return this; + return null; } + /** + * Determines whether or not the background is being hit. + * + * @see #hit(float, float, boolean) + * @param x x-coordinate relative to the bottom-left of the widget. + * @param y y-coordinate relative to the bottom-left of the widget. + * @return {@code true} only if some background element of the widget + * is being hit. (For example, if there are no background + * image or color, then this always returns {@code false}.) + */ + public boolean isBackgroundHit(float x, float y) { + return false; + } + /** * Given a coordinate, find the index of the child (if any). * @@ -768,7 +401,7 @@ public Actor hit(float x, float y, boolean touchable) { public int findChildIndexAtStage(float x, float y) { int childIndex = findIndexFromAngle(angleAtStage(x,y)); stageToLocalCoordinates(vector2.set(x,y)); - return isWithinRadii(vector2.x - getMaxRadius(), vector2.y - getMaxRadius()) + return isWithinRadii(vector2.x - getWidth()/2, vector2.y - getHeight()/2) ? childIndex : getAmountOfChildren(); // "getAmountOfChildren" is equivalent to "invalid" } @@ -801,10 +434,28 @@ public float angleAtStage(float x, float y) { return normalizeAngle( MathUtils.radiansToDegrees * MathUtils.atan2(y - vector2.y, x - vector2.x) - - getRotation() - startDegreesOffset + - getTotalRotation() - startDegreesOffset ); } + /** + * To obtain the rotation value, including the rotation induced + * from the parent Groups.
+ * That is because calling {@link #getRotation()} in scene2d + * only returns the rotation value applied directly to the Actor. + * If a {@link Group} including this Actor is rotated, then even + * though the Actor appears rotated, the internal value will be 0. + * + * @return The total rotation value. + */ + protected float getTotalRotation() { + float rotation = getRotation(); + Group parent = getParent(); + if(parent == null) + return rotation; + return rotation + parent.getRotation(); + } + /** * Used to ensure an angle is in between 0 and 360. * @@ -815,23 +466,50 @@ public float normalizeAngle(float angle) { return ((angle % 360 + 360) % 360); } + /** + * Given a child index, find whether or not it would be a valid candidate to + * highlight or select. + * + * @param index an integer that would usually be the output of + * {@link #findChildIndexAtStage(float, float)}. + * @return {@code true} only if the index is linked to a valid child sector. + */ + public boolean isValidIndex(int index) { + return !(index <= -1 || index >= getAmountOfChildren()); + } + /** * Checks whether or not the input coordinate is in between (inclusively) * the inner-radius and the current radius of the widget (which can - * be bigger than {@link #minRadius} if you use {@link #setFillParent(boolean)}, - * for example). + * be bigger than {@link #preferredRadius} if you use + * {@link #setFillParent(boolean)}, for example). * - * @param x x-coordinate relative to the center of the widget's - * @param y y-coordinate relative to the center of the widget's + * @param x x-coordinate relative to the center of the widget. + * @param y y-coordinate relative to the center of the widget. * @return 'true' only if the coordinates fall within the widget's radii. */ public boolean isWithinRadii(float x, float y) { float distance = pow2(x) + pow2(y); float innerRadSquared = pow2(getInnerRadiusLength()); - float radSquared = pow2(getMaxRadius()); + float radSquared = pow2(getCurrentRadius()); return distance >= innerRadSquared && distance <= radSquared; } + /** + * Checks whether or not the input coordinate is within (exclusively) + * the inner-radius. + * + * @param x x-coordinate relative to the center of the widget. + * @param y y-coordinate relative to the center of the widget. + * @return 'true' only if the coordinates fall within the widget's + * inner radius. + */ + public boolean isWithinInnerRadius(float x, float y) { + float distance = pow2(x) + pow2(y); + float innerRadSquared = pow2(getInnerRadiusLength()); + return distance < innerRadSquared; + } + /** * Returns the input to the power of 2. * @@ -865,19 +543,8 @@ public void centerOnScreen() { public void centerOnActor(Actor actor) { if(actor == null) return; - setPosition(actor.getX(Align.center), actor.getY(Align.center), Align.center); - } - - /** - * Given a child index, find whether or not it would be a valid candidate to - * highlight or select. - * - * @param index an integer that would usually be the output of - * {@link #findChildIndexAtStage(float, float)}. - * @return {@code true} only if the index is linked to a valid child sector. - */ - public boolean isValidIndex(int index) { - return !(index <= -1 || index >= getAmountOfChildren()); + actor.localToStageCoordinates(vector2.set(actor.getWidth()/2, actor.getHeight()/2)); + setPosition(vector2.x, vector2.y, Align.center); } @@ -891,167 +558,6 @@ public void drawRudimentaryDebug() { - /* - =================================== STYLE ================================== - */ - - - /** - * Returns the label's style. Modifying the returned style may not have an - * effect until {@link #setStyle(RadialGroupStyle)} is called.
- * It's probable that your code will look like this (to give you an idea): - *
-     * {@code
-     * radialGroup.getStyle().whatYouWantToChange = someNewValue;
-     * radialGroup.setStyle(radialGroup.getStyle());
-     * }
-     * 
- * - * @return the Style that defines this Widget. This style contains information - * about what is the value of the radius or the width of the separators, for - * example. - */ - public RadialGroupStyle getStyle() { - return style; - } - - - /** - * Runs checks before assigning the style to the Widget. Only a valid style - * will pass the test. - * - * @param style the style that will be checked before being assigned. - */ - public void setStyle(RadialGroupStyle style) { - checkStyle(style); - this.style = style; - invalidate(); - } - - /** - * Ensures the input values for the given style are valid. - * - * @param style a style class you want to check properties of. - */ - protected void checkStyle(RadialGroupStyle style) { - if(style == null) - throw new IllegalArgumentException("style cannot be null."); - - if(style.separatorWidth < 0) - throw new IllegalArgumentException("separatorWidth cannot be negative."); - - if(style.circumferenceWidth < 0) - throw new IllegalArgumentException("circumferenceWidth cannot be negative."); - - if(style.sliceColor == null && style.alternateSliceColor != null) - throw new IllegalArgumentException("sliceColor must also be specified if you are defining alternateSliceColor. " + - "You can however only specify the sliceColor, if you want."); - } - - /** - * Encompasses the characteristics that define the style of the Widget - * to be drawn. - */ - public static class RadialGroupStyle { - - /** - * Recommended. Optional.
- * A background that will be drawn behind everything else within the Widget.
- * Be mindful of the fact that this is unaffected by any of the other - * variables: it will be resized to fit in the whole region that - * represents the position, width and height of the widget. - */ - public Drawable background; - - /** - * Optional.
- * A background color that, if provided, will be drawn over the - * background image and below everything else.
- * It mostly acts as a quick set up option if you do not have an image - * for you background. - */ - public Color backgroundColor; - - /** - * Recommended. Optional.
- * The color used by the separating lines between each item.
- * It is recommended mostly for the case where you are not defining an - * {@link #alternateSliceColor}.
- * If you do not define a {@link #separatorWidth} along with this value, - * no lines will be visible. - */ - public Color separatorColor; - - /** - * Recommended. Optional.
- * The color used to fill the "pie sectors" (i.e. slice) of each item.
- * Consider using a fairly low alpha value if you are providing a - * {@link #background} {@link Drawable}. - */ - public Color sliceColor; - - /** - * Optional.
- * If this color is set, the "pie sectors" will alternate between the - * {@link #sliceColor} and this one so that their defining region - * is more easily distinguished. - */ - public Color alternateSliceColor; - - /** - * Optional.
- * The color used for the line that defines the circumference of the - * Widget. If the Widget is not a complete a circle, this will only be - * applied along the partial circumference.
- * If you have set a non-zero {@link #innerRadiusPercent} value, this will - * also apply to the "inner radius" of your Widget.
- * If you do not define a {@link #circumferenceWidth} along with this - * value, no circumference will be visible. - */ - public Color circumferenceColor; - - /** - * Recommended. Optional.
- * Determines how wide the lines that separate each slice will be.
- * If no {@link #separatorColor} was provided along with this value, - * no lines will be drawn. - */ - public float separatorWidth; - - /** - * Optional.
- * Determines how wide the circumference line will be.
- * If no {@link #circumferenceColor} was provided along with this value, - * no circumference will be drawn. - */ - public float circumferenceWidth; - - - /** - * Encompasses the characteristics that define the style of the Widget - * to be drawn. - */ - public RadialGroupStyle() { - } - - /** - * Encompasses the characteristics that define the style of the Widget - * to be drawn. - * - * @param style a Style to copy the parameters from. - */ - public RadialGroupStyle(RadialGroupStyle style) { - this.background = style.background; - this.circumferenceWidth = style.circumferenceWidth; - this.circumferenceColor = new Color(style.circumferenceColor); - this.separatorWidth = style.separatorWidth; - this.separatorColor = new Color(style.separatorColor); - this.sliceColor = new Color(style.sliceColor); - this.alternateSliceColor = new Color(style.alternateSliceColor); - this.backgroundColor = new Color(style.backgroundColor); - } - } - @@ -1070,29 +576,6 @@ public int getAmountOfChildren() { return getChildren().size; } - - /** - * @return the ShapeDrawer used to draw everything but the contained Actors. - */ - public ShapeDrawer getShapeDrawer() { - return sd; - } - - /** - * You probably shouldn't be messing with this, but it's provided for - * convenience reasons.
- * For example, it's possible that your widget will be so big that - * the {@link ShapeDrawer} will crash with an Exception while trying to - * draw it. You would then want to use this setter to provide a brand new - * instance which didn't override the {@code estimateSidesRequired(float, float)} - * method to try to increase the smoothness of the curves. - * - * @param sd the new instance of {@link ShapeDrawer} that you want to use. - */ - public void setShapeDrawer(ShapeDrawer sd) { - this.sd = sd; - } - /** * @return the multiplier's value which is applied to all the alpha values * of the things contained by the widget (slices, lines, drawables, etc.) @@ -1115,32 +598,35 @@ public void setGlobalAlphaMultiplier(float globalAlphaMultiplier) { } /** - * @see #minRadius + * @see #preferredRadius * @return The radius that defines how big the Widget will be. */ - public float getMinRadius() { - return minRadius; + public float getPreferredRadius() { + return preferredRadius; } /** * Required.
* The radius that defines how big the Widget will be.
- * This is used as the minimal radius value if anything such as a + * This is generally used as the minimal radius value if anything such as a * {@link com.badlogic.gdx.scenes.scene2d.ui.Table} ends up modifying the * size of the widget. {@link #setFillParent(boolean)} will also end up - * using that radius value as a minimum. + * using that radius value as a minimum.
+ * However, be aware that this value is not respected by the use of + * {@link #setWidth(float)} or {@link #setHeight(float)}. In other words, it + * is possible to set the size of your widget to a smaller value. * - * @param minRadius The value must be bigger than {@value #BUFFER}. + * @param preferredRadius The value must be bigger than {@value #BUFFER}. * If the value is smaller than the current * {@link #innerRadiusPercent} then the * {@link #innerRadiusPercent} is set to a smaller value. */ - public void setMinRadius(float minRadius) { - if(minRadius < BUFFER) + public void setPreferredRadius(float preferredRadius) { + if(preferredRadius < BUFFER) throw new IllegalArgumentException("radius cannot be smaller than " + BUFFER + "."); - if(minRadius != lastRadius) { - this.minRadius = minRadius; - lastRadius = minRadius; + if(preferredRadius != lastRadius) { + this.preferredRadius = preferredRadius; + lastRadius = preferredRadius; setSize(getMinWidth(), getMinHeight()); // for orphan widgets (no parent) @@ -1165,24 +651,24 @@ public float getInnerRadiusPercent() { * @return {@code minRadius * innerRadiusPercent}. */ public float getInnerRadiusLength() { - return getMaxRadius() * innerRadiusPercent; + return getCurrentRadius() * innerRadiusPercent; } /** * Optional.
- * If provided, the {@link RadialGroupStyle#sliceColor} will only fill - * the slice defined between the {@link #minRadius} and its percentage + * If provided, the {@link PieWidgetStyle#sliceColor} will only fill + * the slice defined between the {@link #preferredRadius} and its percentage * value coming from this. A hole will be left into the middle of the Widget, - * like a doughnut, and if a {@link RadialGroupStyle#background} or a - * {@link RadialGroupStyle#backgroundColor} was provided, it will be visible + * like a doughnut, and if a {@link PieWidgetStyle#background} or a + * {@link PieWidgetStyle#backgroundColor} was provided, it will be visible * in the middle.
* Actors inserted into the Widget are placed in the middle between the - * innerRadius and the {@link #minRadius}. That is only the default behavior, + * innerRadius and the {@link #preferredRadius}. That is only the default behavior, * if you want to change that, see {@link #getActorDistanceFromCenter(Actor)}. * * @param innerRadiusPercent How far from the center do the slices start * being drawn, in terms of percentage of the - * {@link #minRadius}.
+ * {@link #preferredRadius}.
* The value must be between 0 (inclusive) * and 1 (exclusive). */ diff --git a/src/test/java/com/payne/games/piemenu/Demonstration.java b/src/test/java/com/payne/games/piemenu/Demonstration.java index 605006f..a4a0665 100644 --- a/src/test/java/com/payne/games/piemenu/Demonstration.java +++ b/src/test/java/com/payne/games/piemenu/Demonstration.java @@ -15,7 +15,11 @@ import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.InputListener; import com.badlogic.gdx.scenes.scene2d.Stage; -import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.scenes.scene2d.ui.Image; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; @@ -37,7 +41,7 @@ public class Demonstration extends ApplicationAdapter { private PieMenu middleMousePie; private PieMenu.PieMenuStyle midStyle1; private PieMenu.PieMenuStyle midStyle2; - private AnimatedRadialGroup radial; + private AnimatedPieWidget radial; private float midStyle1InnerRadius = 24f/80; private float midStyle2InnerRadius = 27f/80; @@ -94,11 +98,11 @@ public void create () { private void setUpRadialWidget(Table root) { /* Setting up and creating the widget. */ - RadialGroup.RadialGroupStyle style = new RadialGroup.RadialGroupStyle(); + PieWidget.PieWidgetStyle style = new PieWidget.PieWidgetStyle(); style.backgroundColor = new Color(1,1,1,1); style.sliceColor = new Color(.4f,.4f,.4f,1); style.alternateSliceColor = new Color(.6f,0,0,1); - radial = new AnimatedRadialGroup(batch, whitePixel, style, 100, .5f, 0, 180); + radial = new AnimatedPieWidget(whitePixel, style, 100, .5f, 0, 180); /* Populating the widget. */ for (int i = 0; i < INITIAL_CHILDREN_AMOUNT; i++) { @@ -132,7 +136,7 @@ private void setUpButtonDragPieMenu(Table root) { style.selectedColor = new Color(.7f,.3f,.5f,1); style.sliceColor = new Color(0,.7f,0,1); style.alternateSliceColor = new Color(.7f,0,0,1); - dragPie = new AnimatedPieMenu(batch, whitePixel, style, 130, 50f/130, 180, 320); + dragPie = new AnimatedPieMenu(whitePixel, style, 130, 50f/130, 180, 320); /* Customizing the behavior. */ dragPie.setInfiniteSelectionRange(true); @@ -187,7 +191,7 @@ public void changed(ChangeEvent event, Actor actor) { * To be used to get the user to transition directly into * {@link InputListener#touchDragged(InputEvent, float, float, int)} * as if he had triggered - * {@link InputListener#touchDown(InputEvent, float, float, int, int)}.
+ * {@link InputListener#touchDown(InputEvent, float, float, int, int)}.
* I am not certain this is the recommended way of doing this, but for the * purposes of this demonstration, it works! * @@ -209,7 +213,7 @@ private void setUpRightMousePieMenu() { style.separatorColor = new Color(.1f,.1f,.1f,1); style.downColor = new Color(.5f,.5f,.5f,1); style.sliceColor = new Color(.33f,.33f,.33f,1); - rightMousePie = new PieMenu(batch, whitePixel, style, 80); + rightMousePie = new PieMenu(whitePixel, style, 80); /* Customizing the behavior. */ rightMousePie.setInfiniteSelectionRange(true); @@ -268,7 +272,7 @@ private void setUpMiddleMousePieMenu() { midStyle1 = new PieMenu.PieMenuStyle(); midStyle1.selectedColor = new Color(1,.5f,.5f,.5f); midStyle1.background = new TextureRegionDrawable(new Texture(Gdx.files.internal("rael_pie.png"))); - middleMousePie = new PieMenu(batch, whitePixel, midStyle1, 80, midStyle1InnerRadius, 30) { + middleMousePie = new PieMenu(whitePixel, midStyle1, 80, midStyle1InnerRadius, 30) { /* Since we are using Images, we want to resize them to fit within each sector. */ @Override public void modifyActor(Actor actor, float degreesPerChild, float actorDistanceFromCenter) { @@ -321,7 +325,7 @@ private void setUpPermaPieMenu() { style.sliceColor = new Color(.33f,.33f,.33f,1); style.alternateSliceColor = new Color(.25f,.25f,.25f,1); style.circumferenceColor = new Color(0,0,0,1); - permaPie = new PieMenu(batch, whitePixel, style, 80, 20f/80, 0 ,180); + permaPie = new PieMenu(whitePixel, style, 80, 20f/80, 0 ,180); /* Adding a selection-listener. */ permaPie.addListener(new ChangeListener() { diff --git a/src/test/java/com/payne/games/piemenu/genericTests/CenterOnActor.java b/src/test/java/com/payne/games/piemenu/genericTests/CenterOnActor.java new file mode 100644 index 0000000..933efc9 --- /dev/null +++ b/src/test/java/com/payne/games/piemenu/genericTests/CenterOnActor.java @@ -0,0 +1,116 @@ +package com.payne.games.piemenu.genericTests; + +import com.badlogic.gdx.ApplicationAdapter; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Group; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.utils.viewport.ScreenViewport; +import com.payne.games.piemenu.PieWidget; + + +public class CenterOnActor extends ApplicationAdapter { + private Skin skin; + private Stage stage; + private Texture tmpTex; + private Batch batch; + private Label testLabel; + private PieWidget widget; + + @Override + public void create() { + + /* Setting up the Stage. */ + skin = new Skin(Gdx.files.internal("skin.json")); + batch = new PolygonSpriteBatch(); + stage = new Stage(new ScreenViewport(), batch); + Gdx.input.setInputProcessor(stage); + stage.setDebugAll(true); + + /* Setting up the WhitePixel. */ + Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888); + pixmap.setColor(1, 1, 1, 1); + pixmap.fill(); + tmpTex = new Texture(pixmap); + pixmap.dispose(); + TextureRegion whitePixel = new TextureRegion(tmpTex); + + + + + + /* Adding the demo widgets. */ + PieWidget.PieWidgetStyle style1 = new PieWidget.PieWidgetStyle(); +// style1.sliceColor = Color.ORANGE; +// style1.alternateSliceColor = new Color(.8f, .5f, .2f, 1); + style1.circumferenceWidth = 2; + style1.circumferenceColor = Color.BLACK; + style1.separatorWidth = 2; + style1.separatorColor = Color.BLACK; + widget = new PieWidget(whitePixel, style1, 200, 0.9f); + + for(int i=0 ; i<4 ; i++) { + TextButton tmp = new TextButton("XXX", skin); + widget.addActor(tmp); + } + + stage.addActor(widget); + + + /* The Group to test coordinates with. */ + Group group = new Group(); + Table table = new Table(skin); + table.add(new Label("Bobbbbbbbbbbbb", skin)); + testLabel = new Label("Test", skin); + table.add(testLabel); + group.addActor(table); + stage.addActor(group); + group.setPosition(250,250); + } + + @Override + public void render() { + + /* Clearing the screen and filling up the background. */ + Gdx.gl.glClearColor(.4f, .4f, .4f, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + /* Updating and drawing the Stage. */ + stage.act(); + stage.draw(); + + widget.centerOnActor(testLabel); + + if (Gdx.input.isKeyPressed(Input.Keys.SPACE)) { + widget.rotateBy(Gdx.graphics.getDeltaTime() * 100); + System.out.println(widget.getRotation()); + } + + } + + @Override + public void resize(int width, int height) { + stage.getViewport().update(width, height, true); + } + + @Override + public void dispose() { + + /* Disposing is good practice! */ + skin.dispose(); + stage.dispose(); + batch.dispose(); + tmpTex.dispose(); + } +} \ No newline at end of file diff --git a/src/test/java/com/payne/games/piemenu/genericTests/DifferentActorsWidget.java b/src/test/java/com/payne/games/piemenu/genericTests/DifferentActorsWidget.java index df6311a..4f98de0 100644 --- a/src/test/java/com/payne/games/piemenu/genericTests/DifferentActorsWidget.java +++ b/src/test/java/com/payne/games/piemenu/genericTests/DifferentActorsWidget.java @@ -45,12 +45,12 @@ public void create () { style.hoverColor = Color.RED; style.selectedColor = Color.BLUE; style.backgroundColor = Color.ORANGE; - menu = new PieMenu(batch, whitePixel, style, 400) { + menu = new PieMenu(whitePixel, style, 400) { @Override public float getActorDistanceFromCenter(Actor actor) { invalidate(); return getAmountOfChildren() > 1 - ? getMaxRadius() - getChild(0).getWidth() + ? getCurrentRadius() - getChild(0).getWidth() : 0; } diff --git a/src/test/java/com/payne/games/piemenu/genericTests/HitInfiniteMiddle.java b/src/test/java/com/payne/games/piemenu/genericTests/HitInfiniteMiddle.java new file mode 100644 index 0000000..04ad786 --- /dev/null +++ b/src/test/java/com/payne/games/piemenu/genericTests/HitInfiniteMiddle.java @@ -0,0 +1,108 @@ +package com.payne.games.piemenu.genericTests; + +import com.badlogic.gdx.ApplicationAdapter; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.utils.viewport.ScreenViewport; +import com.payne.games.piemenu.PieMenu; +import com.payne.games.piemenu.PieMenu.PieMenuStyle; + + +public class HitInfiniteMiddle extends ApplicationAdapter { + private Skin skin; + private Stage stage; + private Texture tmpTex; + private Batch batch; + private PieMenu containerWidget; + + @Override + public void create() { + + /* Setting up the Stage. */ + skin = new Skin(Gdx.files.internal("skin.json")); + batch = new PolygonSpriteBatch(); + stage = new Stage(new ScreenViewport(), batch); + Gdx.input.setInputProcessor(stage); + stage.setDebugAll(true); + + /* Setting up the WhitePixel. */ + Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888); + pixmap.setColor(1, 1, 1, 1); + pixmap.fill(); + tmpTex = new Texture(pixmap); + pixmap.dispose(); + TextureRegion whitePixel = new TextureRegion(tmpTex); + + + + + + /* Adding the demo widgets. */ + PieMenuStyle style1 = new PieMenuStyle(); +// style1.sliceColor = Color.ORANGE; +// style1.alternateSliceColor = new Color(.8f, .5f, .2f, 1); + style1.circumferenceWidth = 2; + style1.circumferenceColor = Color.BLACK; + style1.separatorWidth = 2; + style1.separatorColor = Color.BLACK; + + containerWidget = new PieMenu(whitePixel, style1, 200, 0.9f); + containerWidget.setName("MAIN"); + containerWidget.setInfiniteSelectionRange(true); + containerWidget.setMiddleCancel(true); + + for(int i=0 ; i<5 ; i++) { + TextButton tmp = new TextButton("@@@@@@@@@@@@@@@@@@", skin); + containerWidget.addActor(tmp); + } + + + stage.addActor(containerWidget); + containerWidget.setFillParent(true); + } + + @Override + public void render() { + + /* Clearing the screen and filling up the background. */ + Gdx.gl.glClearColor(.4f, .4f, .4f, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + /* Updating and drawing the Stage. */ + stage.act(); + stage.draw(); + + containerWidget.centerOnScreen(); + + if (Gdx.input.isKeyPressed(Input.Keys.SPACE)) { + containerWidget.rotateBy(Gdx.graphics.getDeltaTime() * 100); + System.out.println(containerWidget.getRotation()); + } + + } + + @Override + public void resize(int width, int height) { + stage.getViewport().update(width, height, true); + } + + @Override + public void dispose() { + + /* Disposing is good practice! */ + skin.dispose(); + stage.dispose(); + batch.dispose(); + tmpTex.dispose(); + } +} \ No newline at end of file diff --git a/src/test/java/com/payne/games/piemenu/genericTests/HitOutside.java b/src/test/java/com/payne/games/piemenu/genericTests/HitOutside.java new file mode 100644 index 0000000..1d9fc1e --- /dev/null +++ b/src/test/java/com/payne/games/piemenu/genericTests/HitOutside.java @@ -0,0 +1,104 @@ +package com.payne.games.piemenu.genericTests; + +import com.badlogic.gdx.ApplicationAdapter; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.utils.viewport.ScreenViewport; +import com.payne.games.piemenu.PieWidget; + + +public class HitOutside extends ApplicationAdapter { + private Skin skin; + private Stage stage; + private Texture tmpTex; + private Batch batch; + private PieWidget containerWidget; + + @Override + public void create() { + + /* Setting up the Stage. */ + skin = new Skin(Gdx.files.internal("skin.json")); + batch = new PolygonSpriteBatch(); + stage = new Stage(new ScreenViewport(), batch); + Gdx.input.setInputProcessor(stage); + stage.setDebugAll(true); + + /* Setting up the WhitePixel. */ + Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888); + pixmap.setColor(1, 1, 1, 1); + pixmap.fill(); + tmpTex = new Texture(pixmap); + pixmap.dispose(); + TextureRegion whitePixel = new TextureRegion(tmpTex); + + + + + + /* Adding the demo widgets. */ + PieWidget.PieWidgetStyle style1 = new PieWidget.PieWidgetStyle(); +// style1.sliceColor = Color.ORANGE; +// style1.alternateSliceColor = new Color(.8f, .5f, .2f, 1); + style1.circumferenceWidth = 2; + style1.circumferenceColor = Color.BLACK; + style1.separatorWidth = 2; + style1.separatorColor = Color.BLACK; + containerWidget = new PieWidget(whitePixel, style1, 200, 0.9f); + containerWidget.setName("MAIN"); + + for(int i=0 ; i<5 ; i++) { + TextButton tmp = new TextButton("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", skin); + containerWidget.addActor(tmp); + } + + + stage.addActor(containerWidget); +// containerWidget.setFillParent(true); + } + + @Override + public void render() { + + /* Clearing the screen and filling up the background. */ + Gdx.gl.glClearColor(.4f, .4f, .4f, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + /* Updating and drawing the Stage. */ + stage.act(); + stage.draw(); + + containerWidget.centerOnScreen(); + + if (Gdx.input.isKeyPressed(Input.Keys.SPACE)) { + containerWidget.rotateBy(Gdx.graphics.getDeltaTime() * 100); + System.out.println(containerWidget.getRotation()); + } + + } + + @Override + public void resize(int width, int height) { + stage.getViewport().update(width, height, true); + } + + @Override + public void dispose() { + + /* Disposing is good practice! */ + skin.dispose(); + stage.dispose(); + batch.dispose(); + tmpTex.dispose(); + } +} \ No newline at end of file diff --git a/src/test/java/com/payne/games/piemenu/genericTests/MgsxTests.java b/src/test/java/com/payne/games/piemenu/genericTests/MgsxTests.java index e4fd2fb..892f4aa 100644 --- a/src/test/java/com/payne/games/piemenu/genericTests/MgsxTests.java +++ b/src/test/java/com/payne/games/piemenu/genericTests/MgsxTests.java @@ -34,7 +34,7 @@ public void create() { // Group group = new Group(); -// PieMenu menu = new PieMenu(stage.getBatch(), skin.getRegion("white"), PieMenuUtils.getStyle(), SIZE, .2f); +// PieMenu menu = new PieMenu(skin.getRegion("white"), PieMenuUtils.getStyle(), SIZE, .2f); // fillMenu(menu, skin, "A", "D", "E"); // group.addActor(menu); // menu.pack(); @@ -44,7 +44,7 @@ public void create() { // Group group2 = new Group(); -// PieMenu menu2 = new PieMenu(stage.getBatch(), skin.getRegion("white"), PieMenuUtils.getStyle(), SIZE, .2f); +// PieMenu menu2 = new PieMenu(skin.getRegion("white"), PieMenuUtils.getStyle(), SIZE, .2f); // fillMenu(menu2, skin, "A", "D", "E"); // group2.addActor(menu2); // menu2.setPieMenuListener(new InputListener()); @@ -52,7 +52,7 @@ public void create() { // stage.addActor(group2); -// PieMenu menu3 = new PieMenu(stage.getBatch(), skin.getRegion("white"), PieMenuUtils.getStyle(), SIZE, .2f); +// PieMenu menu3 = new PieMenu(skin.getRegion("white"), PieMenuUtils.getStyle(), SIZE, .2f); // fillMenu(menu3, skin, "A", "D", "E"); // menu3.pack(); // menu3.setPosition(200, 200); @@ -147,7 +147,7 @@ public SettingsPOC(Stage stage, Skin skin) { float offsetX = spaceX; // floating case (OK) - menu = new PieMenu(stage.getBatch(), skin.getRegion("white"), style, SIZE, .2f); + menu = new PieMenu(skin.getRegion("white"), style, SIZE, .2f); fillMenu(menu, skin, "A", "B", "C"); menu.pack(); menu.setPosition(offsetX, stage.getHeight() - menu.getHeight()); @@ -159,7 +159,7 @@ public SettingsPOC(Stage stage, Skin skin) { // floating table case. (KO) table = new Table(skin); table.add("Title very long").row(); - menu = new PieMenu(stage.getBatch(), skin.getRegion("white"), style, SIZE, .2f); + menu = new PieMenu(skin.getRegion("white"), style, SIZE, .2f); fillMenu(menu, skin, "A", "D", "E"); table.add(menu); table.pack(); @@ -170,7 +170,7 @@ public SettingsPOC(Stage stage, Skin skin) { // floating table case 2. (KO) table = new Table(skin); - menu = new PieMenu(stage.getBatch(), skin.getRegion("white"), style, SIZE, .2f); + menu = new PieMenu(skin.getRegion("white"), style, SIZE, .2f); fillMenu(menu, skin, "A", "F", "G"); table.add(menu).row(); table.add("Title").row(); @@ -183,7 +183,7 @@ public SettingsPOC(Stage stage, Skin skin) { // floating table with multiple. (KO) table = new Table(skin); for (int i = 0; i < 3; i++) { - menu = new PieMenu(stage.getBatch(), skin.getRegion("white"), style, SIZE, .2f); + menu = new PieMenu(skin.getRegion("white"), style, SIZE, .2f); fillMenu(menu, skin, "A", "H", "I"); table.add(menu); addListeners(menu); @@ -195,7 +195,7 @@ public SettingsPOC(Stage stage, Skin skin) { // floating table case with grow. (KO) table = new Table(skin); - menu = new PieMenu(stage.getBatch(), skin.getRegion("white"), style, 10, .2f); + menu = new PieMenu(skin.getRegion("white"), style, 10, .2f); fillMenu(menu, skin, "A", "J", "K"); table.add(menu).grow().row(); table.setSize(400, 300); @@ -205,7 +205,7 @@ public SettingsPOC(Stage stage, Skin skin) { // table case with fill parent. (OK) table = new Table(skin); - menu = new PieMenu(stage.getBatch(), skin.getRegion("white"), style, SIZE, .2f); + menu = new PieMenu(skin.getRegion("white"), style, SIZE, .2f); fillMenu(menu, skin, "A", "L", "M"); table.add(menu).expand().right().bottom().row(); table.setFillParent(true); diff --git a/src/test/java/com/payne/games/piemenu/genericTests/RotatingFillParentWidget.java b/src/test/java/com/payne/games/piemenu/genericTests/RotatingFillParentWidget.java index 84188a2..e8cebfe 100644 --- a/src/test/java/com/payne/games/piemenu/genericTests/RotatingFillParentWidget.java +++ b/src/test/java/com/payne/games/piemenu/genericTests/RotatingFillParentWidget.java @@ -52,7 +52,7 @@ public void create () { style.hoverColor = Color.RED; style.selectedColor = Color.BLUE; style.background = new TextureRegionDrawable(new Texture(Gdx.files.internal("rael_pie.png"))); - menu = new PieMenu(batch, whitePixel, style, 80, 24f/80, 30); + menu = new PieMenu(whitePixel, style, 80, 24f/80, 30); menu.setGlobalAlphaMultiplier(.5f); for(int i=0 ; i<6 ; i++) diff --git a/src/test/java/com/payne/games/piemenu/genericTests/SelfContainedPieMenu.java b/src/test/java/com/payne/games/piemenu/genericTests/SelfContainedPieMenu.java new file mode 100644 index 0000000..659070b --- /dev/null +++ b/src/test/java/com/payne/games/piemenu/genericTests/SelfContainedPieMenu.java @@ -0,0 +1,116 @@ +package com.payne.games.piemenu.genericTests; + +import com.badlogic.gdx.ApplicationAdapter; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.utils.viewport.ScreenViewport; +import com.payne.games.piemenu.PieMenu; +import com.payne.games.piemenu.PieWidget; + + +public class SelfContainedPieMenu extends ApplicationAdapter { + private Skin skin; + private Stage stage; + private Texture tmpTex; + private Batch batch; + private PieWidget containerWidget; + + @Override + public void create() { + + /* Setting up the Stage. */ + skin = new Skin(Gdx.files.internal("skin.json")); + batch = new PolygonSpriteBatch(); + stage = new Stage(new ScreenViewport(), batch); + Gdx.input.setInputProcessor(stage); + stage.setDebugAll(true); + + /* Setting up the WhitePixel. */ + Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888); + pixmap.setColor(1, 1, 1, 1); + pixmap.fill(); + tmpTex = new Texture(pixmap); + pixmap.dispose(); + TextureRegion whitePixel = new TextureRegion(tmpTex); + + + + + + /* Adding the demo widgets. */ + PieWidget.PieWidgetStyle style1 = new PieWidget.PieWidgetStyle(); +// style1.sliceColor = Color.ORANGE; +// style1.alternateSliceColor = new Color(.8f, .5f, .2f, 1); + style1.circumferenceWidth = 2; + style1.circumferenceColor = Color.BLACK; + style1.separatorWidth = 2; + style1.separatorColor = Color.BLACK; + containerWidget = new PieWidget(whitePixel, style1, 500, 0.5f); + containerWidget.setName("MAIN"); + + PieMenu.PieMenuStyle style2 = new PieMenu.PieMenuStyle(); + style2.hoverColor = Color.GREEN; + style2.selectedColor = Color.MAGENTA; + style2.backgroundColor = Color.BROWN; + for(int i=0 ; i<5 ; i++) { + PieMenu tmp = new PieMenu(whitePixel, style2, 110); + tmp.setName("menu " + i); + containerWidget.addActor(tmp); + for(int j=0 ; j<5 ; j++) + tmp.addActor(new Label(i + " " + j, skin)); +// tmp.setWidth(50); +// tmp.setHeight(50); + + } + + + stage.addActor(containerWidget); +// containerWidget.setWidth(1600); + containerWidget.setFillParent(true); + } + + @Override + public void render() { + + /* Clearing the screen and filling up the background. */ + Gdx.gl.glClearColor(.4f, .4f, .4f, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + /* Updating and drawing the Stage. */ + stage.act(); + stage.draw(); + + containerWidget.centerOnScreen(); + + if (Gdx.input.isKeyPressed(Input.Keys.SPACE)) { + containerWidget.rotateBy(Gdx.graphics.getDeltaTime() * 100); + System.out.println(containerWidget.getRotation()); + } + + } + + @Override + public void resize(int width, int height) { + stage.getViewport().update(width, height, true); + } + + @Override + public void dispose() { + + /* Disposing is good practice! */ + skin.dispose(); + stage.dispose(); + batch.dispose(); + tmpTex.dispose(); + } +} \ No newline at end of file diff --git a/src/test/java/com/payne/games/piemenu/genericTests/ShapeDrawerLimit.java b/src/test/java/com/payne/games/piemenu/genericTests/ShapeDrawerLimit.java index 7255417..21c44d8 100644 --- a/src/test/java/com/payne/games/piemenu/genericTests/ShapeDrawerLimit.java +++ b/src/test/java/com/payne/games/piemenu/genericTests/ShapeDrawerLimit.java @@ -52,7 +52,7 @@ public void create() { style1.hoverColor = Color.RED; style1.selectedColor = Color.BLUE; style1.backgroundColor = Color.ORANGE; - menu = new PieMenu(batch, whitePixel, style1, 250); // at "5092" it crashes + menu = new PieMenu(whitePixel, style1, 250); // at "5092" it crashes for(int i=0 ; i<5 ; i++) menu.addActor(new Label("menu " + i, skin)); diff --git a/src/test/java/com/payne/games/piemenu/genericTests/TableWidgets.java b/src/test/java/com/payne/games/piemenu/genericTests/TableWidgets.java index 435fdaa..084c9a7 100644 --- a/src/test/java/com/payne/games/piemenu/genericTests/TableWidgets.java +++ b/src/test/java/com/payne/games/piemenu/genericTests/TableWidgets.java @@ -10,12 +10,7 @@ import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.Stage; -import com.badlogic.gdx.scenes.scene2d.ui.Button; -import com.badlogic.gdx.scenes.scene2d.ui.ImageTextButton; -import com.badlogic.gdx.scenes.scene2d.ui.Label; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.ui.Table; -import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.ui.*; import com.badlogic.gdx.utils.viewport.ScreenViewport; import com.payne.games.piemenu.PieMenu; @@ -64,7 +59,7 @@ public void create () { style1.hoverColor = Color.RED; style1.selectedColor = Color.BLUE; style1.backgroundColor = Color.ORANGE; - PieMenu menu1 = new PieMenu(batch, whitePixel, style1, 80); + PieMenu menu1 = new PieMenu(whitePixel, style1, 80); menu1.setName("left widget"); for(int i=0 ; i<5 ; i++) @@ -80,7 +75,7 @@ public void create () { style2.hoverColor = Color.RED; style2.selectedColor = Color.BLUE; style2.backgroundColor = Color.ORANGE; - PieMenu menu2 = new PieMenu(batch, whitePixel, style2, 120); + PieMenu menu2 = new PieMenu(whitePixel, style2, 120); menu2.setName("right widget"); for(int i=0 ; i<5 ; i++) @@ -99,7 +94,7 @@ public void create () { style3.hoverColor = Color.RED; style3.selectedColor = Color.BLUE; style3.backgroundColor = Color.ORANGE; - PieMenu menu3 = new PieMenu(batch, whitePixel, style3, 40); + PieMenu menu3 = new PieMenu(whitePixel, style3, 40); for(int i=0 ; i<5 ; i++) menu3.addActor(new Label("menu " + i, skin)); diff --git a/src/test/java/com/payne/games/piemenu/individuals/ButtonBound.java b/src/test/java/com/payne/games/piemenu/individuals/ButtonBound.java index 80dbdf0..55cabf2 100644 --- a/src/test/java/com/payne/games/piemenu/individuals/ButtonBound.java +++ b/src/test/java/com/payne/games/piemenu/individuals/ButtonBound.java @@ -67,7 +67,7 @@ public void create () { style.selectedColor = new Color(.7f,.3f,.5f,1); style.sliceColor = new Color(0,.7f,0,1); style.alternateSliceColor = new Color(.7f,0,0,1); - menu = new AnimatedPieMenu(batch, whitePixel, style, 130, 50f/130, 180, 320); + menu = new AnimatedPieMenu(whitePixel, style, 130, 50f/130, 180, 320); /* Customizing the behavior. */ menu.setInfiniteSelectionRange(true); 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 498b8c1..91de7bf 100644 --- a/src/test/java/com/payne/games/piemenu/individuals/ButtonToggle.java +++ b/src/test/java/com/payne/games/piemenu/individuals/ButtonToggle.java @@ -18,8 +18,8 @@ import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.viewport.ScreenViewport; -import com.payne.games.piemenu.AnimatedRadialGroup; -import com.payne.games.piemenu.RadialGroup; +import com.payne.games.piemenu.AnimatedPieWidget; +import com.payne.games.piemenu.PieWidget; public class ButtonToggle extends ApplicationAdapter { @@ -27,7 +27,7 @@ public class ButtonToggle extends ApplicationAdapter { private Stage stage; private Texture tmpTex; private Batch batch; - private AnimatedRadialGroup radGroup; + private AnimatedPieWidget radGroup; @Override @@ -60,13 +60,13 @@ public void create () { \==================================================================== */ /* Setting up and creating the widget. */ - RadialGroup.RadialGroupStyle style = new RadialGroup.RadialGroupStyle(); + PieWidget.PieWidgetStyle style = new PieWidget.PieWidgetStyle(); style.sliceColor = new Color(1,1,1,.2f); style.separatorWidth = 2; style.circumferenceWidth = 2; style.circumferenceColor = Color.BLACK; style.separatorColor = style.circumferenceColor; - radGroup = new AnimatedRadialGroup(batch, whitePixel, style, 110, 50f/110, 315, 270); + radGroup = new AnimatedPieWidget(whitePixel, style, 110, 50f/110, 315, 270); /* Populating the widget. */ for (int i = 0; i < 8; i++) { diff --git a/src/test/java/com/payne/games/piemenu/individuals/ClickDrag.java b/src/test/java/com/payne/games/piemenu/individuals/ClickDrag.java index 81432c7..d9e5a99 100644 --- a/src/test/java/com/payne/games/piemenu/individuals/ClickDrag.java +++ b/src/test/java/com/payne/games/piemenu/individuals/ClickDrag.java @@ -64,7 +64,7 @@ public void create () { style.separatorColor = new Color(.1f,.1f,.1f,1); style.downColor = new Color(.5f,.5f,.5f,1); style.sliceColor = new Color(.33f,.33f,.33f,1); - menu = new PieMenu(batch, whitePixel, style, 80); + menu = new PieMenu(whitePixel, style, 80); /* Customizing the behavior. */ menu.setInfiniteSelectionRange(true); diff --git a/src/test/java/com/payne/games/piemenu/individuals/ClickToggle.java b/src/test/java/com/payne/games/piemenu/individuals/ClickToggle.java index f624ff4..add1fd7 100644 --- a/src/test/java/com/payne/games/piemenu/individuals/ClickToggle.java +++ b/src/test/java/com/payne/games/piemenu/individuals/ClickToggle.java @@ -56,7 +56,7 @@ public void create () { PieMenu.PieMenuStyle style = new PieMenu.PieMenuStyle(); style.background = new TextureRegionDrawable(new Texture(Gdx.files.internal("rael_pie.png"))); // image background! style.selectedColor = new Color(1,.5f,.5f,.5f); - menu = new PieMenu(batch, whitePixel, style, 80, 24f/80, 30) { + menu = new PieMenu(whitePixel, style, 80, 24f/80, 30) { /* Since we are using Images, we want to resize them to fit within each sector. */ @Override public void modifyActor(Actor actor, float degreesPerChild, float actorDistanceFromCenter) { diff --git a/src/test/java/com/payne/games/piemenu/individuals/CustomAnimation.java b/src/test/java/com/payne/games/piemenu/individuals/CustomAnimation.java index b7936d8..3af8a03 100644 --- a/src/test/java/com/payne/games/piemenu/individuals/CustomAnimation.java +++ b/src/test/java/com/payne/games/piemenu/individuals/CustomAnimation.java @@ -52,13 +52,13 @@ protected int estimateSidesRequired(float radiusX, float radiusY) { style.downColor = new Color(1,.05f,.05f,.4f); style.hoverColor = new Color(.8f,.8f,.8f,.05f); style.hoverSelectedColor = new Color(1,.2f,.2f,.55f); - pieMenu = new PieMenu(batch, skin.getRegion("white"), style, BASE_RADIUS) { + pieMenu = new PieMenu(skin.getRegion("white"), style, BASE_RADIUS) { @Override public float getActorDistanceFromCenter(Actor actor) { /* We want the Labels to be placed closer to the edge than the default value. */ return getAmountOfChildren() > 1 - ? getMaxRadius() - getChild(0).getWidth() + ? getCurrentRadius() - getChild(0).getWidth() : 0; } @@ -69,7 +69,7 @@ public void act(float delta) { /* Our custom animation! */ time += delta*5; pieMenu.setStartDegreesOffset((time * 10) % 360); - pieMenu.setMinRadius(MathUtils.sin(time) * 20 + BASE_RADIUS); + pieMenu.setPreferredRadius(MathUtils.sin(time) * 20 + BASE_RADIUS); // pieMenu.setInnerRadius(Math.abs(MathUtils.sin(time)/(float)Math.PI +.1f)); pieMenu.centerOnScreen(); } diff --git a/src/test/java/com/payne/games/piemenu/individuals/KeyMap.java b/src/test/java/com/payne/games/piemenu/individuals/KeyMap.java index 3f8f91b..d547f8a 100644 --- a/src/test/java/com/payne/games/piemenu/individuals/KeyMap.java +++ b/src/test/java/com/payne/games/piemenu/individuals/KeyMap.java @@ -13,17 +13,14 @@ import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.Stage; -import com.badlogic.gdx.scenes.scene2d.ui.Container; -import com.badlogic.gdx.scenes.scene2d.ui.Image; -import com.badlogic.gdx.scenes.scene2d.ui.Label; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.ui.Stack; +import com.badlogic.gdx.scenes.scene2d.ui.*; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.viewport.ScreenViewport; import com.payne.games.piemenu.PieMenu; + import java.util.HashSet; @@ -63,7 +60,7 @@ public void create () { style.background = new TextureRegionDrawable(new Texture(Gdx.files.internal("rael_pie.png"))); // image background! style.selectedColor = new Color(1,.5f,.5f,.5f); style.downColor = new Color(1,.8f,.8f,.5f); - menu = new PieMenu(batch, whitePixel, style, 80, 24f/80, 30) { + menu = new PieMenu(whitePixel, style, 80, 24f/80, 30) { /* Since we are using Images, we want to resize them to fit within each sector. */ @Override public void modifyActor(Actor actor, float degreesPerChild, float actorDistanceFromCenter) { diff --git a/src/test/java/com/payne/games/piemenu/individuals/Permanent.java b/src/test/java/com/payne/games/piemenu/individuals/Permanent.java index c953ad6..6a37bc6 100644 --- a/src/test/java/com/payne/games/piemenu/individuals/Permanent.java +++ b/src/test/java/com/payne/games/piemenu/individuals/Permanent.java @@ -61,7 +61,7 @@ public void create () { style.sliceColor = new Color(.33f,.33f,.33f,1); style.alternateSliceColor = new Color(.25f,.25f,.25f,1); style.circumferenceColor = new Color(0,0,0,1); - menu = new PieMenu(batch, whitePixel, style, 100, 30f/100, 0 ,180); + menu = new PieMenu(whitePixel, style, 100, 30f/100, 0 ,180); /* Adding a selection-listener. */ menu.addListener(new ChangeListener() { diff --git a/src/test/java/com/payne/games/piemenu/individuals/RadialButtons.java b/src/test/java/com/payne/games/piemenu/individuals/RadialButtons.java new file mode 100644 index 0000000..b8a4b19 --- /dev/null +++ b/src/test/java/com/payne/games/piemenu/individuals/RadialButtons.java @@ -0,0 +1,142 @@ +package com.payne.games.piemenu.individuals; + +import com.badlogic.gdx.ApplicationAdapter; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.viewport.ScreenViewport; +import com.payne.games.piemenu.PieMenu; +import com.payne.games.piemenu.RadialGroup; + + +public class RadialButtons extends ApplicationAdapter { + private Skin skin; + private Stage stage; + private Batch batch; + private RadialGroup menu; + + /* For the demonstration's purposes. Not actually necessary. */ + private float red = .25f; + private float blue = .75f; + private float green = .25f; + + + @Override + public void create () { + + /* Setting up the Stage. */ + skin = new Skin(Gdx.files.internal("skin.json")); + batch = new PolygonSpriteBatch(); + stage = new Stage(new ScreenViewport(), batch); + Gdx.input.setInputProcessor(stage); + + + + /* ====================================================================\ + | HERE BEGINS THE MORE SPECIFIC CODE | + \==================================================================== */ + + /* Setting up and creating the widget. */ + PieMenu.PieMenuStyle style = new PieMenu.PieMenuStyle(); + style.backgroundColor = new Color(1,1,1,.3f); + style.selectedColor = new Color(.7f,.3f,.5f,1); + style.sliceColor = new Color(0,.7f,0,1); + style.alternateSliceColor = new Color(.7f,0,0,1); + menu = new RadialGroup(200, .7f); + + /* Populating the widget. */ + for (int i = 0; i < 9; i++) { + final int tmp = i; + String name; + switch(i) { + case 0: + name = "-BLUE-"; + break; + case 3: + name = "-RED-"; + break; + case 6: + name = "-GREEN-"; + break; + default: + name = "white"; + break; + } + TextButton btn = new TextButton(name, skin); + btn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + switch(tmp) { + case 0: + red = .25f; + blue = .75f; + green = .25f; + break; + case 3: + red = .75f; + blue = .25f; + green = .25f; + break; + case 6: + red = .25f; + blue = .25f; + green = .75f; + break; + default: + red = .75f; + blue = .75f; + green = .75f; + break; + } + } + }); + menu.addActor(btn); + } + + /* Setting up the demo-button. */ + final TextButton textButton = new TextButton("Show buttons", skin); + textButton.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + menu.setVisible(!menu.isVisible()); + } + }); + textButton.setPosition(Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight()/2, Align.center); + stage.addActor(textButton); + + /* Including the widget in the Stage. */ + stage.addActor(menu); + menu.setVisible(false); + menu.centerOnActor(textButton); + } + + + @Override + public void render () { + + /* Clearing the screen and filling up the background. */ + Gdx.gl.glClearColor(red, green, blue, 1); // updated with the menu + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + /* Drawing the Stage (no need to update with `Stage#act()`). */ + stage.draw(); + } + + + @Override + public void dispose () { + + /* Disposing is good practice! */ + stage.dispose(); + batch.dispose(); + skin.dispose(); + } +}