Java tutorial
/** Copyright (C) 2012 * Jason Valestin (valestin@gmail.com ) and Arindam Nath (strider2023@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package radialdemo; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.support.v4.app.Fragment; import android.util.AttributeSet; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.widget.PopupWindow; /** * This is the core class that handles the widget display and user interaction. * * @author Jason Valestin (valestin@gmail.com ) * @author Arindam Nath (strider2023@gmail.com) */ public class RadialMenuWidget extends View { private RadialMenuHelper helper; private List<RadialMenuItem> menuEntries = new ArrayList<RadialMenuItem>(); private RadialMenuItem centerCircle = null; private float screen_density = getContext().getResources().getDisplayMetrics().density; private int defaultColor = Color.rgb(34, 96, 120); // default color of wedge // pieces private int defaultAlpha = 180; // transparency of the colors, 255=Opague, // 0=Transparent private int wedge2Color = Color.rgb(50, 50, 50); // default color of wedge // pieces private int wedge2Alpha = 210; private int outlineColor = Color.rgb(150, 150, 150); // color of outline private int outlineAlpha = 255; // transparency of outline private int selectedColor = Color.rgb(70, 130, 180); // color to fill when // something is // selected private int selectedAlpha = 210; // transparency of fill when something is // selected private int disabledColor = Color.rgb(34, 96, 120); // color to fill when // something is selected private int disabledAlpha = 100; // transparency of fill when something is // selected private int pictureAlpha = 255; // transparency of images private int textColor = Color.rgb(255, 255, 255); // color to fill when // something is selected private int textAlpha = 255; // transparency of fill when something is // selected private int headerTextColor = Color.rgb(255, 255, 255); // color of header // text private int headerTextAlpha = 255; // transparency of header text private int headerBackgroundColor = Color.rgb(0, 0, 0); // color of header // background private int headerBackgroundAlpha = 180; // transparency of header // background private int wedgeQty = 1; // Number of wedges private RadialMenuWedge[] Wedges = new RadialMenuWedge[wedgeQty]; private RadialMenuWedge selected = null; // Keeps track of which wedge is // selected private RadialMenuWedge enabled = null; // Keeps track of which wedge is // enabled for outer ring private Rect[] iconRect = new Rect[wedgeQty]; private int wedgeQty2 = 1; // Number of wedges private RadialMenuWedge[] Wedges2 = new RadialMenuWedge[wedgeQty2]; private RadialMenuWedge selected2 = null; // Keeps track of which wedge is // selected private Rect[] iconRect2 = new Rect[wedgeQty2]; private RadialMenuInterface wedge2Data = null; // Keeps track off which menuItem // data is being used for the // outer ring private int MinSize = scalePX(35); // Radius of inner ring size private int MaxSize = scalePX(90); // Radius of outer ring size private int r2MinSize = MaxSize + scalePX(5); // Radius of inner second ring // size private int r2MaxSize = r2MinSize + scalePX(45); // Radius of outer second // ring size private int MinIconSize = scalePX(15); // Min Size of Image in Wedge private int MaxIconSize = scalePX(35); // Max Size of Image in Wedge // private int BitmapSize = scalePX(40); //Size of Image in Wedge private int cRadius = MinSize - scalePX(7); // Inner Circle Radius private int textSize = scalePX(15); // TextSize private int animateTextSize = textSize; private int xPosition = scalePX(120); // Center X location of Radial Menu private int yPosition = scalePX(120); // Center Y location of Radial Menu private int xSource = 0; // Source X of clicked location private int ySource = 0; // Center Y of clicked location private boolean showSource = false; // Display icon where at source location private boolean inWedge = false; // Identifies touch event was in first // wedge private boolean inWedge2 = false; // Identifies touch event was in second // wedge private boolean inCircle = false; // Identifies touch event was in middle // circle private boolean Wedge2Shown = false; // Identifies 2nd wedge is drawn private boolean HeaderBoxBounded = false; // Identifies if header box is // drawn private String headerString = null; private int headerTextSize = textSize; // TextSize private int headerBuffer = scalePX(8); private Rect textRect = new Rect(); private RectF textBoxRect = new RectF(); private int headerTextLeft; private int headerTextBottom; private static final int ANIMATE_IN = 1; private static final int ANIMATE_OUT = 2; private int animateSections = 4; private int r2VariableSize; private boolean animateOuterIn = false; private boolean animateOuterOut = false; private PopupWindow mWindow; /** * Radial menu widget constructor. * @param context - Application Context. * <strong> Usage </strong> * * RadialMenuWidget pieMenu = new RadialMenuWidget(this); * pieMenu.addMenuEntry(menuItem); * pieMenu.show(view); */ public RadialMenuWidget(Context context) { super(context); helper = new RadialMenuHelper(); mWindow = helper.initPopup(context); // Gets screen specs and defaults to center of screen this.xPosition = (getResources().getDisplayMetrics().widthPixels) / 2; this.yPosition = (getResources().getDisplayMetrics().heightPixels) / 2; determineWedges(); helper.onOpenAnimation(this, xPosition, yPosition, xSource, ySource); } public RadialMenuWidget(Context context, AttributeSet attrs) { super(context, attrs); helper = new RadialMenuHelper(); mWindow = helper.initPopup(context); // Gets screen specs and defaults to center of screen this.xPosition = (getResources().getDisplayMetrics().widthPixels) / 2; this.yPosition = (getResources().getDisplayMetrics().heightPixels) / 2; determineWedges(); helper.onOpenAnimation(this, xPosition, yPosition, xSource, ySource); } @Override public boolean onTouchEvent(MotionEvent e) { int state = e.getAction(); int eventX = (int) e.getX(); int eventY = (int) e.getY(); if (state == MotionEvent.ACTION_DOWN) { // selected = null; // selected2 = null; inWedge = false; inWedge2 = false; inCircle = false; // Checks if a pie slice is selected in first Wedge for (int i = 0; i < Wedges.length; i++) { RadialMenuWedge f = Wedges[i]; double slice = (2 * Math.PI) / wedgeQty; double start = (2 * Math.PI) * (0.75) - (slice / 2); // this is // done // so // top // slice // is // the // centered // on // top // of // the // circle inWedge = helper.pntInWedge(eventX, eventY, xPosition, yPosition, MinSize, MaxSize, (i * slice) + start, slice); if (inWedge == true) { selected = f; break; } } // Checks if a pie slice is selected in second Wedge if (Wedge2Shown == true) { for (int i = 0; i < Wedges2.length; i++) { RadialMenuWedge f = Wedges2[i]; double slice = (2 * Math.PI) / wedgeQty2; double start = (2 * Math.PI) * (0.75) - (slice / 2); // this // is // done // so // top // slice // is // the // centered // on // top // of // the // circle inWedge2 = helper.pntInWedge(eventX, eventY, xPosition, yPosition, r2MinSize, r2MaxSize, (i * slice) + start, slice); if (inWedge2 == true) { selected2 = f; break; } } } // Checks if center is there and is selected if (centerCircle != null) { inCircle = helper.pntInCircle(eventX, eventY, xPosition, yPosition, cRadius); } } else if (state == MotionEvent.ACTION_UP) { // execute commands... // put in stuff here to "return" the button that was pressed. if (inCircle == true) { if (Wedge2Shown == true) { enabled = null; animateOuterIn = true; // sets Wedge2Shown = false; } selected = null; centerCircle.menuActiviated(); } else if (selected != null) { for (int i = 0; i < Wedges.length; i++) { RadialMenuWedge f = Wedges[i]; if (f == selected) { // Checks if a inner ring is enabled if so closes the // outer ring an if (enabled != null) { enabled = null; animateOuterIn = true; // sets Wedge2Shown = false; // If outer ring is not enabled, then executes event } else { menuEntries.get(i).menuActiviated(); // Figures out how many outer rings if (menuEntries.get(i).getChildren() != null) { determineOuterWedges(menuEntries.get(i)); enabled = f; animateOuterOut = true; // sets Wedge2Shown = // true; } else { Wedge2Shown = false; } } selected = null; } } } else if (selected2 != null) { for (int i = 0; i < Wedges2.length; i++) { RadialMenuWedge f = Wedges2[i]; if (f == selected2) { animateOuterIn = true; // sets Wedge2Shown = false; enabled = null; selected = null; wedge2Data.getChildren().get(i).menuActiviated(); } } } else { // This is when something outside the circle or any of the rings // is selected //dismiss(); // selected = null; // enabled = null; } // selected = null; selected2 = null; inCircle = false; } invalidate(); return true; } @Override protected void onDraw(Canvas c) { Paint paint = new Paint(); paint.setAntiAlias(true); paint.setStrokeWidth(3); // draws a dot at the source of the press if (showSource == true) { paint.setColor(outlineColor); paint.setAlpha(outlineAlpha); paint.setStyle(Paint.Style.STROKE); c.drawCircle(xSource, ySource, cRadius / 10, paint); paint.setColor(selectedColor); paint.setAlpha(selectedAlpha); paint.setStyle(Paint.Style.FILL); c.drawCircle(xSource, ySource, cRadius / 10, paint); } //inner for (int i = 0; i < Wedges.length; i++) { RadialMenuWedge f = Wedges[i]; paint.setColor(outlineColor); paint.setAlpha(outlineAlpha); paint.setStyle(Paint.Style.STROKE); c.drawPath(f, paint); if (f == enabled && Wedge2Shown == true) { paint.setColor(wedge2Color); paint.setAlpha(wedge2Alpha); paint.setStyle(Paint.Style.FILL); c.drawPath(f, paint); } else if (f != enabled && Wedge2Shown == true) { paint.setColor(disabledColor); paint.setAlpha(disabledAlpha); paint.setStyle(Paint.Style.FILL); c.drawPath(f, paint); } else if (f == enabled && Wedge2Shown == false) { paint.setColor(wedge2Color); paint.setAlpha(wedge2Alpha); paint.setStyle(Paint.Style.FILL); c.drawPath(f, paint); } else if (f == selected) { paint.setColor(wedge2Color); paint.setAlpha(wedge2Alpha); paint.setStyle(Paint.Style.FILL); c.drawPath(f, paint); } else { paint.setColor(defaultColor); paint.setAlpha(defaultAlpha); paint.setStyle(Paint.Style.FILL); c.drawPath(f, paint); } //button content Rect rf = iconRect[i]; if ((menuEntries.get(i).getIcon() != 0) && (menuEntries.get(i).getLabel() != null)) { // This will look for a "new line" and split into multiple lines String menuItemName = menuEntries.get(i).getLabel(); String[] stringArray = menuItemName.split("\n"); paint.setColor(textColor); if (f != enabled && Wedge2Shown == true) { paint.setAlpha(disabledAlpha); } else { paint.setAlpha(textAlpha); } paint.setStyle(Paint.Style.FILL); paint.setTextSize(textSize); Rect rect = new Rect(); float textHeight = 0; for (int j = 0; j < stringArray.length; j++) { paint.getTextBounds(stringArray[j], 0, stringArray[j].length(), rect); textHeight = textHeight + (rect.height() + 3); } Rect rf2 = new Rect(); rf2.set(rf.left, rf.top - ((int) textHeight / 2), rf.right, rf.bottom - ((int) textHeight / 2)); float textBottom = rf2.bottom; for (int j = 0; j < stringArray.length; j++) { paint.getTextBounds(stringArray[j], 0, stringArray[j].length(), rect); float textLeft = rf.centerX() - rect.width() / 2; textBottom = textBottom + (rect.height() + 3); c.drawText(stringArray[j], textLeft - rect.left, textBottom - rect.bottom, paint); } // Puts in the Icon Drawable drawable = getResources().getDrawable(menuEntries.get(i).getIcon()); drawable.setBounds(rf2); if (f != enabled && Wedge2Shown == true) { drawable.setAlpha(disabledAlpha); } else { drawable.setAlpha(pictureAlpha); } drawable.draw(c); // Icon Only } else if (menuEntries.get(i).getIcon() != 0) { // Puts in the Icon Drawable drawable = getResources().getDrawable(menuEntries.get(i).getIcon()); drawable.setBounds(rf); if (f != enabled && Wedge2Shown == true) { drawable.setAlpha(disabledAlpha); } else { drawable.setAlpha(pictureAlpha); } drawable.draw(c); // Text Only } else { // Puts in the Text if no Icon paint.setColor(textColor); if (f != enabled && Wedge2Shown == true) { paint.setAlpha(disabledAlpha); } else { paint.setAlpha(textAlpha); } paint.setStyle(Paint.Style.FILL); paint.setTextSize(textSize + 10); // This will look for a "new line" and split into multiple lines String menuItemName = menuEntries.get(i).getLabel(); String[] stringArray = menuItemName.split("\n"); // gets total height Rect rect = new Rect(); float textHeight = 0; for (int j = 0; j < stringArray.length; j++) { paint.getTextBounds(stringArray[j], 0, stringArray[j].length(), rect); textHeight = textHeight + (rect.height() + 3); } float textBottom = rf.centerY() - (textHeight / 2); for (int j = 0; j < stringArray.length; j++) { paint.getTextBounds(stringArray[j], 0, stringArray[j].length(), rect); float textLeft = rf.centerX() - rect.width() / 2; textBottom = textBottom + (rect.height() + 3); c.drawText(stringArray[j], textLeft - rect.left, textBottom - rect.bottom, paint); } } } // Animate the outer ring in/out if (animateOuterIn == true) { animateOuterWedges(ANIMATE_IN); } else if (animateOuterOut == true) { animateOuterWedges(ANIMATE_OUT); } //outer if (Wedge2Shown == true) { for (int i = 0; i < Wedges2.length; i++) { RadialMenuWedge f = Wedges2[i]; paint.setColor(outlineColor); paint.setAlpha(20); paint.setStyle(Paint.Style.STROKE); c.drawPath(f, paint); if (f == selected2) { paint.setColor(selectedColor); paint.setAlpha(selectedAlpha); paint.setStyle(Paint.Style.FILL); c.drawPath(f, paint); } else { paint.setColor(wedge2Color); paint.setAlpha(wedge2Alpha); paint.setStyle(Paint.Style.FILL); c.drawPath(f, paint); } Rect rf = iconRect2[i]; if ((wedge2Data.getChildren().get(i).getIcon() != 0) && (wedge2Data.getChildren().get(i).getLabel() != null)) { // This will look for a "new line" and split into multiple // lines String menuItemName = wedge2Data.getChildren().get(i).getLabel(); String[] stringArray = menuItemName.split("\n"); paint.setColor(textColor); paint.setAlpha(textAlpha); paint.setStyle(Paint.Style.FILL); paint.setTextSize(animateTextSize); Rect rect = new Rect(); float textHeight = 0; for (int j = 0; j < stringArray.length; j++) { paint.getTextBounds(stringArray[j], 0, stringArray[j].length(), rect); textHeight = textHeight + (rect.height() + 3); } Rect rf2 = new Rect(); rf2.set(rf.left, rf.top - ((int) textHeight / 2), rf.right, rf.bottom - ((int) textHeight / 2)); float textBottom = rf2.bottom; for (int j = 0; j < stringArray.length; j++) { paint.getTextBounds(stringArray[j], 0, stringArray[j].length(), rect); float textLeft = rf.centerX() - rect.width() / 2; textBottom = textBottom + (rect.height() + 3); c.drawText(stringArray[j], textLeft - rect.left, textBottom - rect.bottom, paint); } // Puts in the Icon Drawable drawable = getResources().getDrawable(wedge2Data.getChildren().get(i).getIcon()); drawable.setBounds(rf2); drawable.setAlpha(pictureAlpha); drawable.draw(c); // Icon Only } else if (wedge2Data.getChildren().get(i).getIcon() != 0) { // Puts in the Icon Drawable drawable = getResources().getDrawable(wedge2Data.getChildren().get(i).getIcon()); drawable.setBounds(rf); drawable.setAlpha(pictureAlpha); drawable.draw(c); // Text Only } else { // Puts in the Text if no Icon paint.setColor(textColor); paint.setAlpha(textAlpha); paint.setStyle(Paint.Style.FILL); paint.setTextSize(animateTextSize); // This will look for a "new line" and split into multiple // lines String menuItemName = wedge2Data.getChildren().get(i).getLabel(); String[] stringArray = menuItemName.split("\n"); // gets total height Rect rect = new Rect(); float textHeight = 0; for (int j = 0; j < stringArray.length; j++) { paint.getTextBounds(stringArray[j], 0, stringArray[j].length(), rect); textHeight = textHeight + (rect.height() + 3); } float textBottom = rf.centerY() - (textHeight / 2); for (int j = 0; j < stringArray.length; j++) { paint.getTextBounds(stringArray[j], 0, stringArray[j].length(), rect); float textLeft = rf.centerX() - rect.width() / 2; textBottom = textBottom + (rect.height() + 3); c.drawText(stringArray[j], textLeft - rect.left, textBottom - rect.bottom, paint); } } } } //Check if the user has given input for centre circle if (centerCircle != null) { // Draws the Middle Circle paint.setColor(outlineColor); paint.setAlpha(outlineAlpha); paint.setStyle(Paint.Style.STROKE); c.drawCircle(xPosition, yPosition, cRadius, paint); if (inCircle == true) { paint.setColor(selectedColor); paint.setAlpha(selectedAlpha); paint.setStyle(Paint.Style.FILL); c.drawCircle(xPosition, yPosition, cRadius, paint); helper.onCloseAnimation(this, xPosition, yPosition, xSource, ySource); } else { paint.setColor(defaultColor); paint.setAlpha(defaultAlpha); paint.setStyle(Paint.Style.FILL); c.drawCircle(xPosition, yPosition, cRadius, paint); } // Draw the circle picture if ((centerCircle.getIcon() != 0) && (centerCircle.getLabel() != null)) { // This will look for a "new line" and split into multiple lines String menuItemName = centerCircle.getLabel(); String[] stringArray = menuItemName.split("\n"); paint.setColor(textColor); paint.setAlpha(textAlpha); paint.setStyle(Paint.Style.FILL); paint.setTextSize(textSize); Rect rectText = new Rect(); Rect rectIcon = new Rect(); Drawable drawable = getResources().getDrawable(centerCircle.getIcon()); int h = getIconSize(drawable.getIntrinsicHeight(), MinIconSize, MaxIconSize); int w = getIconSize(drawable.getIntrinsicWidth(), MinIconSize, MaxIconSize); rectIcon.set(xPosition - w / 2, yPosition - h / 2, xPosition + w / 2, yPosition + h / 2); float textHeight = 0; for (int j = 0; j < stringArray.length; j++) { paint.getTextBounds(stringArray[j], 0, stringArray[j].length(), rectText); textHeight = textHeight + (rectText.height() + 3); } rectIcon.set(rectIcon.left, rectIcon.top - ((int) textHeight / 2), rectIcon.right, rectIcon.bottom - ((int) textHeight / 2)); float textBottom = rectIcon.bottom; for (int j = 0; j < stringArray.length; j++) { paint.getTextBounds(stringArray[j], 0, stringArray[j].length(), rectText); float textLeft = xPosition - rectText.width() / 2; textBottom = textBottom + (rectText.height() + 3); c.drawText(stringArray[j], textLeft - rectText.left, textBottom - rectText.bottom, paint); } // Puts in the Icon drawable.setBounds(rectIcon); drawable.setAlpha(pictureAlpha); drawable.draw(c); // Icon Only } else if (centerCircle.getIcon() != 0) { Rect rect = new Rect(); Drawable drawable = getResources().getDrawable(centerCircle.getIcon()); int h = getIconSize(drawable.getIntrinsicHeight(), MinIconSize, MaxIconSize); int w = getIconSize(drawable.getIntrinsicWidth(), MinIconSize, MaxIconSize); rect.set(xPosition - w / 2, yPosition - h / 2, xPosition + w / 2, yPosition + h / 2); drawable.setBounds(rect); drawable.setAlpha(pictureAlpha); drawable.draw(c); // Text Only } else { // Puts in the Text if no Icon paint.setColor(textColor); paint.setAlpha(textAlpha); paint.setStyle(Paint.Style.FILL); paint.setTextSize(textSize); // This will look for a "new line" and split into multiple lines String menuItemName = centerCircle.getLabel(); String[] stringArray = menuItemName.split("\n"); // gets total height Rect rect = new Rect(); float textHeight = 0; for (int j = 0; j < stringArray.length; j++) { paint.getTextBounds(stringArray[j], 0, stringArray[j].length(), rect); textHeight = textHeight + (rect.height() + 3); } float textBottom = yPosition - (textHeight / 2); for (int j = 0; j < stringArray.length; j++) { paint.getTextBounds(stringArray[j], 0, stringArray[j].length(), rect); float textLeft = xPosition - rect.width() / 2; textBottom = textBottom + (rect.height() + 3); c.drawText(stringArray[j], textLeft - rect.left, textBottom - rect.bottom, paint); } } } // Draws Text in TextBox if (headerString != null) { paint.setTextSize(headerTextSize); paint.getTextBounds(headerString, 0, headerString.length(), this.textRect); if (HeaderBoxBounded == false) { determineHeaderBox(); HeaderBoxBounded = true; } paint.setColor(outlineColor); paint.setAlpha(outlineAlpha); paint.setStyle(Paint.Style.STROKE); c.drawRoundRect(this.textBoxRect, scalePX(5), scalePX(5), paint); paint.setColor(headerBackgroundColor); paint.setAlpha(headerBackgroundAlpha); paint.setStyle(Paint.Style.FILL); c.drawRoundRect(this.textBoxRect, scalePX(5), scalePX(5), paint); paint.setColor(headerTextColor); paint.setAlpha(headerTextAlpha); paint.setStyle(Paint.Style.FILL); paint.setTextSize(headerTextSize); c.drawText(headerString, headerTextLeft, headerTextBottom, paint); } } private int scalePX(int dp_size) { int px_size = (int) (dp_size * screen_density + 0.5f); return px_size; } private int getIconSize(int iconSize, int minSize, int maxSize) { if (iconSize > minSize) { if (iconSize > maxSize) { return maxSize; } else { // iconSize < maxSize return iconSize; } } else { // iconSize < minSize return minSize; } } private void animateOuterWedges(int animation_direction) { boolean animationComplete = false; // Wedge 2 float slice2 = 360 / wedgeQty2; float start_slice2 = 270 - (slice2 / 2); // calculates where to put the images double rSlice2 = (2 * Math.PI) / wedgeQty2; double rStart2 = (2 * Math.PI) * (0.75) - (rSlice2 / 2); this.Wedges2 = new RadialMenuWedge[wedgeQty2]; this.iconRect2 = new Rect[wedgeQty2]; Wedge2Shown = true; int wedgeSizeChange = (r2MaxSize - r2MinSize) / animateSections; if (animation_direction == ANIMATE_OUT) { if (r2MinSize + r2VariableSize + wedgeSizeChange < r2MaxSize) { r2VariableSize += wedgeSizeChange; } else { animateOuterOut = false; r2VariableSize = r2MaxSize - r2MinSize; animationComplete = true; } // animates text size change this.animateTextSize = (textSize / animateSections) * (r2VariableSize / wedgeSizeChange); // calculates new wedge sizes for (int i = 0; i < Wedges2.length; i++) { this.Wedges2[i] = new RadialMenuWedge(xPosition, yPosition, r2MinSize, r2MinSize + r2VariableSize, (i * slice2) + start_slice2, slice2); float xCenter = (float) (Math.cos(((rSlice2 * i) + (rSlice2 * 0.5)) + rStart2) * (r2MinSize + r2VariableSize + r2MinSize) / 2) + xPosition; float yCenter = (float) (Math.sin(((rSlice2 * i) + (rSlice2 * 0.5)) + rStart2) * (r2MinSize + r2VariableSize + r2MinSize) / 2) + yPosition; int h = MaxIconSize; int w = MaxIconSize; if (wedge2Data.getChildren().get(i).getIcon() != 0) { Drawable drawable = getResources().getDrawable(wedge2Data.getChildren().get(i).getIcon()); h = getIconSize(drawable.getIntrinsicHeight(), MinIconSize, MaxIconSize); w = getIconSize(drawable.getIntrinsicWidth(), MinIconSize, MaxIconSize); } if (r2VariableSize < h) { h = r2VariableSize; } if (r2VariableSize < w) { w = r2VariableSize; } this.iconRect2[i] = new Rect((int) xCenter - w / 2, (int) yCenter - h / 2, (int) xCenter + w / 2, (int) yCenter + h / 2); int widthOffset = MaxSize; if (widthOffset < this.textRect.width() / 2) { widthOffset = this.textRect.width() / 2 + scalePX(3); } this.textBoxRect.set((xPosition - (widthOffset)), (int) (yPosition - (r2MinSize + r2VariableSize) - headerBuffer - this.textRect.height() - scalePX(3)), (xPosition + (widthOffset)), (yPosition - (r2MinSize + r2VariableSize) - headerBuffer + scalePX(3))); this.headerTextBottom = yPosition - (r2MinSize + r2VariableSize) - headerBuffer - this.textRect.bottom; } } else if (animation_direction == ANIMATE_IN) { if (r2MinSize < r2MaxSize - r2VariableSize - wedgeSizeChange) { r2VariableSize += wedgeSizeChange; } else { animateOuterIn = false; r2VariableSize = r2MaxSize; animationComplete = true; } // animates text size change this.animateTextSize = textSize - ((textSize / animateSections) * (r2VariableSize / wedgeSizeChange)); for (int i = 0; i < Wedges2.length; i++) { this.Wedges2[i] = new RadialMenuWedge(xPosition, yPosition, r2MinSize, r2MaxSize - r2VariableSize, (i * slice2) + start_slice2, slice2); float xCenter = (float) (Math.cos(((rSlice2 * i) + (rSlice2 * 0.5)) + rStart2) * (r2MaxSize - r2VariableSize + r2MinSize) / 2) + xPosition; float yCenter = (float) (Math.sin(((rSlice2 * i) + (rSlice2 * 0.5)) + rStart2) * (r2MaxSize - r2VariableSize + r2MinSize) / 2) + yPosition; int h = MaxIconSize; int w = MaxIconSize; if (wedge2Data.getChildren().get(i).getIcon() != 0) { Drawable drawable = getResources().getDrawable(wedge2Data.getChildren().get(i).getIcon()); h = getIconSize(drawable.getIntrinsicHeight(), MinIconSize, MaxIconSize); w = getIconSize(drawable.getIntrinsicWidth(), MinIconSize, MaxIconSize); } if (r2MaxSize - r2MinSize - r2VariableSize < h) { h = r2MaxSize - r2MinSize - r2VariableSize; } if (r2MaxSize - r2MinSize - r2VariableSize < w) { w = r2MaxSize - r2MinSize - r2VariableSize; } this.iconRect2[i] = new Rect((int) xCenter - w / 2, (int) yCenter - h / 2, (int) xCenter + w / 2, (int) yCenter + h / 2); // computes header text box int heightOffset = r2MaxSize - r2VariableSize; int widthOffset = MaxSize; if (MaxSize > r2MaxSize - r2VariableSize) { heightOffset = MaxSize; } if (widthOffset < this.textRect.width() / 2) { widthOffset = this.textRect.width() / 2 + scalePX(3); } this.textBoxRect.set((xPosition - (widthOffset)), (int) (yPosition - (heightOffset) - headerBuffer - this.textRect.height() - scalePX(3)), (xPosition + (widthOffset)), (yPosition - (heightOffset) - headerBuffer + scalePX(3))); this.headerTextBottom = yPosition - (heightOffset) - headerBuffer - this.textRect.bottom; } } if (animationComplete == true) { r2VariableSize = 0; this.animateTextSize = textSize; if (animation_direction == ANIMATE_IN) { Wedge2Shown = false; } } invalidate(); // re-draws the picture } private void determineWedges() { int entriesQty = menuEntries.size(); if (entriesQty > 0) { wedgeQty = entriesQty; float degSlice = 360 / wedgeQty; float start_degSlice = 270 - (degSlice / 2); // calculates where to put the images double rSlice = (2 * Math.PI) / wedgeQty; double rStart = (2 * Math.PI) * (0.75) - (rSlice / 2); this.Wedges = new RadialMenuWedge[wedgeQty]; this.iconRect = new Rect[wedgeQty]; for (int i = 0; i < Wedges.length; i++) { this.Wedges[i] = new RadialMenuWedge(xPosition, yPosition, MinSize, MaxSize, (i * degSlice) + start_degSlice, degSlice); float xCenter = (float) (Math.cos(((rSlice * i) + (rSlice * 0.5)) + rStart) * (MaxSize + MinSize) / 2) + xPosition; float yCenter = (float) (Math.sin(((rSlice * i) + (rSlice * 0.5)) + rStart) * (MaxSize + MinSize) / 2) + yPosition; int h = MaxIconSize; int w = MaxIconSize; if (menuEntries.get(i).getIcon() != 0) { Drawable drawable = getResources().getDrawable(menuEntries.get(i).getIcon()); h = getIconSize(drawable.getIntrinsicHeight(), MinIconSize, MaxIconSize); w = getIconSize(drawable.getIntrinsicWidth(), MinIconSize, MaxIconSize); } this.iconRect[i] = new Rect((int) xCenter - w / 2, (int) yCenter - h / 2, (int) xCenter + w / 2, (int) yCenter + h / 2); } invalidate(); // re-draws the picture } } private void determineOuterWedges(RadialMenuItem entry) { int entriesQty = entry.getChildren().size(); wedgeQty2 = entriesQty; // Wedge 2 float degSlice2 = 360 / wedgeQty2; float start_degSlice2 = 270 - (degSlice2 / 2); // calculates where to put the images double rSlice2 = (2 * Math.PI) / wedgeQty2; double rStart2 = (2 * Math.PI) * (0.75) - (rSlice2 / 2); this.Wedges2 = new RadialMenuWedge[wedgeQty2]; this.iconRect2 = new Rect[wedgeQty2]; for (int i = 0; i < Wedges2.length; i++) { this.Wedges2[i] = new RadialMenuWedge(xPosition, yPosition, r2MinSize, r2MaxSize, (i * degSlice2) + start_degSlice2, degSlice2); float xCenter = (float) (Math.cos(((rSlice2 * i) + (rSlice2 * 0.5)) + rStart2) * (r2MaxSize + r2MinSize) / 2) + xPosition; float yCenter = (float) (Math.sin(((rSlice2 * i) + (rSlice2 * 0.5)) + rStart2) * (r2MaxSize + r2MinSize) / 2) + yPosition; int h = MaxIconSize; int w = MaxIconSize; if (entry.getChildren().get(i).getIcon() != 0) { Drawable drawable = getResources().getDrawable(entry.getChildren().get(i).getIcon()); h = getIconSize(drawable.getIntrinsicHeight(), MinIconSize, MaxIconSize); w = getIconSize(drawable.getIntrinsicWidth(), MinIconSize, MaxIconSize); } this.iconRect2[i] = new Rect((int) xCenter - w / 2, (int) yCenter - h / 2, (int) xCenter + w / 2, (int) yCenter + h / 2); } this.wedge2Data = entry; invalidate(); // re-draws the picture } private void determineHeaderBox() { this.headerTextLeft = xPosition - this.textRect.width() / 2; this.headerTextBottom = yPosition - (MaxSize) - headerBuffer - this.textRect.bottom; int offset = MaxSize; if (offset < this.textRect.width() / 2) { offset = this.textRect.width() / 2 + scalePX(3); } this.textBoxRect.set((xPosition - (offset)), (int) (yPosition - (MaxSize) - headerBuffer - this.textRect.height() - scalePX(3)), (xPosition + (offset)), (yPosition - (MaxSize) - headerBuffer + scalePX(3))); } /****************************************************************************************************************************** * ADD ITEM METHODS ******************************************************************************************************************************/ /** * This method allows the user to add an array of menu items. * @param menuItems - List object of RadialMenuItem. * @return */ public void addMenuEntry(List<RadialMenuItem> menuItems) { menuEntries.addAll(menuItems); determineWedges(); } /** * This method allows the user to add a menu item. * @param menuItem - Object of RadialMenuItem. * @return */ public void addMenuEntry(RadialMenuItem menuItem) { menuEntries.add(menuItem); determineWedges(); } /****************************************************************************************************************************** * SET METHODS ******************************************************************************************************************************/ /** * <strong> Optional </strong> * This method allows the user to add the central menu item. * @param menuItem - Object of RadialMenuItem. * @return */ public void setCenterCircle(RadialMenuItem menuItem) { centerCircle = menuItem; } /** * <strong> Optional </strong> * Set the middle ring radius of the radial menu widget. * @param InnerRadius - Inner border radius. * @param OuterRadius - Outer border radius. */ public void setInnerRingRadius(int InnerRadius, int OuterRadius) { this.MinSize = scalePX(InnerRadius); this.MaxSize = scalePX(OuterRadius); determineWedges(); } /** * <strong> Optional </strong> * Set the outer ring radius of the radial menu widget. * @param InnerRadius - Inner border radius. * @param OuterRadius - Outer border radius. */ public void setOuterRingRadius(int InnerRadius, int OuterRadius) { this.r2MinSize = scalePX(InnerRadius); this.r2MaxSize = scalePX(OuterRadius); determineWedges(); } /** * <strong> Optional </strong> * This method set the radius of the centre circle. * @param centerRadius - Radius of the circle. */ public void setCenterCircleRadius(int centerRadius) { this.cRadius = scalePX(centerRadius); determineWedges(); } /** * Set the menu items text size. * @param TextSize - Text size of the menu items. */ public void setTextSize(int TextSize) { this.textSize = scalePX(TextSize); this.animateTextSize = this.textSize; } /** * Set the menu item icon size. * @param minIconSize - Minimum scaled size. * @param maxIconSize - Maximum scaled size. */ public void setIconSize(int minIconSize, int maxIconSize) { this.MinIconSize = scalePX(minIconSize); this.MaxIconSize = scalePX(maxIconSize); determineWedges(); } /** * * @param x * @param y */ public void setCenterLocation(int x, int y) { this.xPosition = x; this.yPosition = y; determineWedges(); helper.onOpenAnimation(this, xPosition, yPosition, xSource, ySource); } /** * * @param x * @param y */ public void setSourceLocation(int x, int y) { this.xSource = x; this.ySource = y; helper.onOpenAnimation(this, xPosition, yPosition, xSource, ySource); } /** * @deprecated * @param showSourceLocation */ public void setShowSourceLocation(boolean showSourceLocation) { this.showSource = showSourceLocation; helper.onOpenAnimation(this, xPosition, yPosition, xSource, ySource); } /** * Set the widget animation speed. * @param millis - Time in milliseconds. */ public void setAnimationSpeed(long millis) { helper.onOpenAnimation(this, xPosition, yPosition, xSource, ySource, millis); } /** * Set the radial menu inner ring color. * @param color - Color value . * @param alpha - Alpha blend value. */ public void setInnerRingColor(int color, int alpha) { this.defaultColor = color; this.defaultAlpha = alpha; } /** * Set the radial menu outer ring color. * @param color - Color value . * @param alpha - Alpha blend value. */ public void setOuterRingColor(int color, int alpha) { this.wedge2Color = color; this.wedge2Alpha = alpha; } /** * Set the radial widget outline color. * @param color - Color value . * @param alpha - Alpha blend value. */ public void setOutlineColor(int color, int alpha) { this.outlineColor = color; this.outlineAlpha = alpha; } /** * Set the widget on select color. * @param color - Color value . * @param alpha - Alpha blend value. */ public void setSelectedColor(int color, int alpha) { this.selectedColor = color; this.selectedAlpha = alpha; } /** * Set the widget on disabled color. * @param color - Color value . * @param alpha - Alpha blend value. */ public void setDisabledColor(int color, int alpha) { this.disabledColor = color; this.disabledAlpha = alpha; } /** * Set the widget text color. * @param color - Text color * @param alpha - Text alpha belnd value */ public void setTextColor(int color, int alpha) { this.textColor = color; this.textAlpha = alpha; } /** * <strong> Optional </strong> * Display a header with text along with the displayed radial menu. * @param header - Header text to be displayed. * @param TextSize - Text size. */ public void setHeader(String header, int TextSize) { this.headerString = header; this.headerTextSize = scalePX(TextSize); HeaderBoxBounded = false; } /** * <strong> Optional </strong> * Display a header with text along with the displayed radial menu. This method helps in configuring the display background. * @param TextColor * @param TextAlpha * @param BgColor * @param BgAlpha */ public void setHeaderColors(int TextColor, int TextAlpha, int BgColor, int BgAlpha) { this.headerTextColor = TextColor; this.headerTextAlpha = TextAlpha; this.headerBackgroundColor = BgColor; this.headerBackgroundAlpha = BgAlpha; } /** * Shows the radial menu widget. * @param anchor - View to be anchored to. * @param posX - Position X. Pass 0 if not needed. * @param posY - Position Y. Pass 0 if not needed. */ public void show(View anchor, int posX, int posY) { mWindow.setContentView(this); mWindow.showAtLocation(anchor, Gravity.NO_GRAVITY, posX, posY); } /** * Shows the radial menu widget. * @param anchor - View to be anchored to. */ public void show(View anchor) { mWindow.setContentView(this); mWindow.showAtLocation(anchor, Gravity.NO_GRAVITY, this.xSource, this.ySource); } /** * Shows the radial menu widget. */ public void show() { mWindow.showAtLocation(getRootView(), 0, 200, 200); ; } /** * Dismisses the radial menu widget. */ public void dismiss() { if (mWindow != null) mWindow.dismiss(); } }