diff --git a/CHANGES b/CHANGES index 0265419..0aebc44 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,5 @@ [3.0.0-rc2] +- Introduced a new behavior-flag: `middleCancel` determines if releasing a click from within the inner-radius will trigger the extended selection or the `defaultIndex` selection. - `ChildRegion` is now referred to as `Slice` throughout the API. - Style variables now have shorter names that resemble the `ButtonStyle` naming. - `setDefaultIndex` now changes the `selectedIndex` if it isn't a valid index. diff --git a/media/keyboard.gif b/media/keyboard.gif index ed83e0d..0d8b178 100644 Binary files a/media/keyboard.gif and b/media/keyboard.gif differ diff --git a/src/main/java/com/payne/games/piemenu/PieMenu.java b/src/main/java/com/payne/games/piemenu/PieMenu.java index d886f5b..8e0e4aa 100644 --- a/src/main/java/com/payne/games/piemenu/PieMenu.java +++ b/src/main/java/com/payne/games/piemenu/PieMenu.java @@ -55,6 +55,15 @@ public class PieMenu extends RadialGroup { */ private boolean infiniteSelectionRange = false; + + /** + * Determines whether or not releasing a click within the inner-radius + * should cancel the selection. + * If {@code true} a release in the middle, even if {@link #infiniteSelectionRange} + * is set to {@code true}, will trigger a selection of the {@link #defaultIndex}. + */ + private boolean middleCancel = false; + /** * Defines the way the Widget looks. */ @@ -359,14 +368,35 @@ public void resetHover() { @Override public int findChildIndexAtStage(float x, float y) { int childIndex = findIndexFromAngle(angleAtStage(x,y)); - if(infiniteSelectionRange) - return childIndex; stageToLocalCoordinates(vector2.set(x,y)); + if(infiniteSelectionRange) { + if(middleCancel) + return isWithinInnerRadius(vector2.x - getWidth()/2, vector2.y - getHeight()/2) + ? getAmountOfChildren() // "getAmountOfChildren" is equivalent to "invalid" + : childIndex; + else + return childIndex; + } return isWithinRadii(vector2.x - getWidth()/2, vector2.y - getHeight()/2) ? childIndex : 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 @@ -918,12 +948,32 @@ public boolean isInfiniteSelectionRange() { /** * Determines whether or not selection should only happen if the mouse is * within the radius of the widget. - * @see #infiniteSelectionRange + * @see #middleCancel */ public void setInfiniteSelectionRange(boolean infiniteSelectionRange) { this.infiniteSelectionRange = infiniteSelectionRange; } + /** + * Determines whether or not releasing a click within the inner-radius + * should cancel the selection. + * If {@code true} a release in the middle, even if {@link #infiniteSelectionRange} + * is set to {@code true}, will trigger a selection of the {@link #defaultIndex}. + */ + public boolean isMiddleCancel() { + return middleCancel; + } + + /** + * Determines whether or not releasing a click within the inner-radius + * should cancel the selection. + * If {@code true} a release in the middle, even if {@link #infiniteSelectionRange} + * is set to {@code true}, will trigger a selection of the {@link #defaultIndex}. + */ + public void setMiddleCancel(boolean middleCancel) { + this.middleCancel = middleCancel; + } + /** * Returns the currently selected item's index. A highlighted item can be * considered selected, depending on the customized behavior of the Widget.
diff --git a/src/main/java/com/payne/games/piemenu/RadialGroup.java b/src/main/java/com/payne/games/piemenu/RadialGroup.java index aa2f869..0c94667 100644 --- a/src/main/java/com/payne/games/piemenu/RadialGroup.java +++ b/src/main/java/com/payne/games/piemenu/RadialGroup.java @@ -807,7 +807,7 @@ public float normalizeAngle(float angle) { /** * Checks whether or not the input coordinate is in between (inclusively) - * the {@link #innerRadiusPercent} and the current radius of the widget (which can + * 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). * 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 a0f229f..524c671 100644 --- a/src/test/java/com/payne/games/piemenu/individuals/KeyMap.java +++ b/src/test/java/com/payne/games/piemenu/individuals/KeyMap.java @@ -61,6 +61,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); + style.downColor = new Color(1,.8f,.8f,.5f); menu = new PieMenu(batch, whitePixel, style, 80, 24f/80, 30) { /* Since we are using Images, we want to resize them to fit within each sector. */ @Override @@ -72,6 +73,8 @@ public void modifyActor(Actor actor, float degreesPerChild, float actorDistanceF }; /* Customizing the behavior. */ + menu.setMiddleCancel(true); + menu.setDefaultIndex(2); menu.setInfiniteSelectionRange(true); menu.setPieMenuListener(new PieMenu.PieMenuClickListener() { @@ -148,6 +151,9 @@ public void changed(ChangeEvent event, Actor actor) { imgs.add(getNewStack("coffee-mug.png", Integer.toString(key++))); for (int i = 0; i < imgs.size; i++) menu.addActor(imgs.get(i)); + + + menu.selectIndex(menu.getDefaultIndex()); // because we would like to trigger that index } private Stack getNewStack(String img, String key) { @@ -179,7 +185,6 @@ public void render () { if (Gdx.input.isButtonJustPressed(Input.Buttons.MIDDLE)) { stage.addActor(menu); menu.centerOnMouse(); - menu.resetSelection(); stage.setKeyboardFocus(menu); menu.setVisible(true); }