Initial testing of "coverflow" integration for XMB menus
This commit is contained in:
parent
42f4085ed1
commit
c5c57b77ec
|
@ -52,4 +52,31 @@
|
|||
<attr name="selectorDrawable" format="reference" />
|
||||
</declare-styleable>
|
||||
|
||||
</resources>
|
||||
<!--
|
||||
~ Copyright 2013 David Schreiber
|
||||
~ 2013 John Paul Nalog
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<declare-styleable name="FancyCoverFlow">
|
||||
<attr name="unselectedAlpha" format="float"/>
|
||||
<attr name="unselectedSaturation" format="float"/>
|
||||
<attr name="unselectedScale" format="float"/>
|
||||
<attr name="maxRotation" format="integer"/>
|
||||
<attr name="scaleDownGravity" format="float"/>
|
||||
<attr name="actionDistance" format="integer">
|
||||
<enum name="auto" value="2147483647" />
|
||||
</attr>
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
|
|
|
@ -0,0 +1,383 @@
|
|||
/*
|
||||
* Copyright 2013 David Schreiber
|
||||
* 2013 John Paul Nalog
|
||||
*
|
||||
* 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 at.technikum.mti.fancycoverflow;
|
||||
|
||||
import com.reicast.emulator.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.*;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.Transformation;
|
||||
import android.widget.Gallery;
|
||||
import android.widget.SpinnerAdapter;
|
||||
|
||||
public class FancyCoverFlow extends Gallery {
|
||||
|
||||
// =============================================================================
|
||||
// Constants
|
||||
// =============================================================================
|
||||
|
||||
public static final int ACTION_DISTANCE_AUTO = Integer.MAX_VALUE;
|
||||
|
||||
public static final float SCALEDOWN_GRAVITY_TOP = 0.0f;
|
||||
|
||||
public static final float SCALEDOWN_GRAVITY_CENTER = 0.5f;
|
||||
|
||||
public static final float SCALEDOWN_GRAVITY_BOTTOM = 1.0f;
|
||||
|
||||
// =============================================================================
|
||||
// Private members
|
||||
// =============================================================================
|
||||
|
||||
private float reflectionRatio = 0.4f;
|
||||
|
||||
private int reflectionGap = 20;
|
||||
|
||||
private boolean reflectionEnabled = false;
|
||||
|
||||
/**
|
||||
* TODO: Doc
|
||||
*/
|
||||
private float unselectedAlpha;
|
||||
|
||||
/**
|
||||
* Camera used for view transformation.
|
||||
*/
|
||||
private Camera transformationCamera;
|
||||
|
||||
/**
|
||||
* TODO: Doc
|
||||
*/
|
||||
private int maxRotation = 75;
|
||||
|
||||
/**
|
||||
* Factor (0-1) that defines how much the unselected children should be scaled down. 1 means no scaledown.
|
||||
*/
|
||||
private float unselectedScale;
|
||||
|
||||
/**
|
||||
* TODO: Doc
|
||||
*/
|
||||
private float scaleDownGravity = SCALEDOWN_GRAVITY_CENTER;
|
||||
|
||||
/**
|
||||
* Distance in pixels between the transformation effects (alpha, rotation, zoom) are applied.
|
||||
*/
|
||||
private int actionDistance;
|
||||
|
||||
/**
|
||||
* Saturation factor (0-1) of items that reach the outer effects distance.
|
||||
*/
|
||||
private float unselectedSaturation;
|
||||
|
||||
// =============================================================================
|
||||
// Constructors
|
||||
// =============================================================================
|
||||
|
||||
public FancyCoverFlow(Context context) {
|
||||
super(context);
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
public FancyCoverFlow(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
this.initialize();
|
||||
this.applyXmlAttributes(attrs);
|
||||
}
|
||||
|
||||
public FancyCoverFlow(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
this.initialize();
|
||||
this.applyXmlAttributes(attrs);
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
this.transformationCamera = new Camera();
|
||||
this.setSpacing(0);
|
||||
}
|
||||
|
||||
private void applyXmlAttributes(AttributeSet attrs) {
|
||||
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.FancyCoverFlow);
|
||||
|
||||
this.actionDistance = a.getInteger(R.styleable.FancyCoverFlow_actionDistance, ACTION_DISTANCE_AUTO);
|
||||
this.scaleDownGravity = a.getFloat(R.styleable.FancyCoverFlow_scaleDownGravity, 1.0f);
|
||||
this.maxRotation = a.getInteger(R.styleable.FancyCoverFlow_maxRotation, 45);
|
||||
this.unselectedAlpha = a.getFloat(R.styleable.FancyCoverFlow_unselectedAlpha, 0.3f);
|
||||
this.unselectedSaturation = a.getFloat(R.styleable.FancyCoverFlow_unselectedSaturation, 0.0f);
|
||||
this.unselectedScale = a.getFloat(R.styleable.FancyCoverFlow_unselectedScale, 0.75f);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Getter / Setter
|
||||
// =============================================================================
|
||||
|
||||
public float getReflectionRatio() {
|
||||
return reflectionRatio;
|
||||
}
|
||||
|
||||
public void setReflectionRatio(float reflectionRatio) {
|
||||
if (reflectionRatio <= 0 || reflectionRatio > 0.5f) {
|
||||
throw new IllegalArgumentException("reflectionRatio may only be in the interval (0, 0.5]");
|
||||
}
|
||||
|
||||
this.reflectionRatio = reflectionRatio;
|
||||
|
||||
if (this.getAdapter() != null) {
|
||||
((FancyCoverFlowAdapter) this.getAdapter()).notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public int getReflectionGap() {
|
||||
return reflectionGap;
|
||||
}
|
||||
|
||||
public void setReflectionGap(int reflectionGap) {
|
||||
this.reflectionGap = reflectionGap;
|
||||
|
||||
if (this.getAdapter() != null) {
|
||||
((FancyCoverFlowAdapter) this.getAdapter()).notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isReflectionEnabled() {
|
||||
return reflectionEnabled;
|
||||
}
|
||||
|
||||
public void setReflectionEnabled(boolean reflectionEnabled) {
|
||||
this.reflectionEnabled = reflectionEnabled;
|
||||
|
||||
if (this.getAdapter() != null) {
|
||||
((FancyCoverFlowAdapter) this.getAdapter()).notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to provide a {@link FancyCoverFlowAdapter} to the coverflow. This
|
||||
* method will throw an {@link ClassCastException} if the passed adapter does not
|
||||
* subclass {@link FancyCoverFlowAdapter}.
|
||||
*
|
||||
* @param adapter
|
||||
*/
|
||||
@Override
|
||||
public void setAdapter(SpinnerAdapter adapter) {
|
||||
if (!(adapter instanceof FancyCoverFlowAdapter)) {
|
||||
throw new ClassCastException(FancyCoverFlow.class.getSimpleName() + " only works in conjunction with a " + FancyCoverFlowAdapter.class.getSimpleName());
|
||||
}
|
||||
|
||||
super.setAdapter(adapter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum rotation that is applied to items left and right of the center of the coverflow.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getMaxRotation() {
|
||||
return maxRotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum rotation that is applied to items left and right of the center of the coverflow.
|
||||
*
|
||||
* @param maxRotation
|
||||
*/
|
||||
public void setMaxRotation(int maxRotation) {
|
||||
this.maxRotation = maxRotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write doc
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getUnselectedAlpha() {
|
||||
return this.unselectedAlpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write doc
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getUnselectedScale() {
|
||||
return unselectedScale;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write doc
|
||||
*
|
||||
* @param unselectedScale
|
||||
*/
|
||||
public void setUnselectedScale(float unselectedScale) {
|
||||
this.unselectedScale = unselectedScale;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Doc
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getScaleDownGravity() {
|
||||
return scaleDownGravity;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Doc
|
||||
*
|
||||
* @param scaleDownGravity
|
||||
*/
|
||||
public void setScaleDownGravity(float scaleDownGravity) {
|
||||
this.scaleDownGravity = scaleDownGravity;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write doc
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getActionDistance() {
|
||||
return actionDistance;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write doc
|
||||
*
|
||||
* @param actionDistance
|
||||
*/
|
||||
public void setActionDistance(int actionDistance) {
|
||||
this.actionDistance = actionDistance;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write doc
|
||||
*
|
||||
* @param unselectedAlpha
|
||||
*/
|
||||
@Override
|
||||
public void setUnselectedAlpha(float unselectedAlpha) {
|
||||
super.setUnselectedAlpha(unselectedAlpha);
|
||||
this.unselectedAlpha = unselectedAlpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write doc
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getUnselectedSaturation() {
|
||||
return unselectedSaturation;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write doc
|
||||
*
|
||||
* @param unselectedSaturation
|
||||
*/
|
||||
public void setUnselectedSaturation(float unselectedSaturation) {
|
||||
this.unselectedSaturation = unselectedSaturation;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Supertype overrides
|
||||
// =============================================================================
|
||||
|
||||
@Override
|
||||
protected boolean getChildStaticTransformation(View child, Transformation t) {
|
||||
// We can cast here because FancyCoverFlowAdapter only creates wrappers.
|
||||
FancyCoverFlowItemWrapper item = (FancyCoverFlowItemWrapper) child;
|
||||
|
||||
// Since Jelly Bean childs won't get invalidated automatically, needs to be added for the smooth coverflow animation
|
||||
if (android.os.Build.VERSION.SDK_INT >= 16) {
|
||||
item.invalidate();
|
||||
}
|
||||
|
||||
final int coverFlowWidth = this.getWidth();
|
||||
final int coverFlowCenter = coverFlowWidth / 2;
|
||||
final int childWidth = item.getWidth();
|
||||
final int childHeight = item.getHeight();
|
||||
final int childCenter = item.getLeft() + childWidth / 2;
|
||||
|
||||
// Use coverflow width when its defined as automatic.
|
||||
final int actionDistance = (this.actionDistance == ACTION_DISTANCE_AUTO) ? (int) ((coverFlowWidth + childWidth) / 2.0f) : this.actionDistance;
|
||||
|
||||
// Calculate the abstract amount for all effects.
|
||||
final float effectsAmount = Math.min(1.0f, Math.max(-1.0f, (1.0f / actionDistance) * (childCenter - coverFlowCenter)));
|
||||
|
||||
// Clear previous transformations and set transformation type (matrix + alpha).
|
||||
t.clear();
|
||||
t.setTransformationType(Transformation.TYPE_BOTH);
|
||||
|
||||
// Alpha
|
||||
if (this.unselectedAlpha != 1) {
|
||||
final float alphaAmount = (this.unselectedAlpha - 1) * Math.abs(effectsAmount) + 1;
|
||||
t.setAlpha(alphaAmount);
|
||||
}
|
||||
|
||||
// Saturation
|
||||
if (this.unselectedSaturation != 1) {
|
||||
// Pass over saturation to the wrapper.
|
||||
final float saturationAmount = (this.unselectedSaturation - 1) * Math.abs(effectsAmount) + 1;
|
||||
item.setSaturation(saturationAmount);
|
||||
}
|
||||
|
||||
final Matrix imageMatrix = t.getMatrix();
|
||||
|
||||
// Apply rotation.
|
||||
if (this.maxRotation != 0) {
|
||||
final int rotationAngle = (int) (-effectsAmount * this.maxRotation);
|
||||
this.transformationCamera.save();
|
||||
this.transformationCamera.rotateY(rotationAngle);
|
||||
this.transformationCamera.getMatrix(imageMatrix);
|
||||
this.transformationCamera.restore();
|
||||
}
|
||||
|
||||
// Zoom.
|
||||
if (this.unselectedScale != 1) {
|
||||
final float zoomAmount = (this.unselectedScale - 1) * Math.abs(effectsAmount) + 1;
|
||||
// Calculate the scale anchor (y anchor can be altered)
|
||||
final float translateX = childWidth / 2.0f;
|
||||
final float translateY = childHeight * this.scaleDownGravity;
|
||||
imageMatrix.preTranslate(-translateX, -translateY);
|
||||
imageMatrix.postScale(zoomAmount, zoomAmount);
|
||||
imageMatrix.postTranslate(translateX, translateY);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Public classes
|
||||
// =============================================================================
|
||||
|
||||
public static class LayoutParams extends Gallery.LayoutParams {
|
||||
public LayoutParams(Context c, AttributeSet attrs) {
|
||||
super(c, attrs);
|
||||
}
|
||||
|
||||
public LayoutParams(int w, int h) {
|
||||
super(w, h);
|
||||
}
|
||||
|
||||
public LayoutParams(ViewGroup.LayoutParams source) {
|
||||
super(source);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright 2013 David Schreiber
|
||||
* 2013 John Paul Nalog
|
||||
*
|
||||
* 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 at.technikum.mti.fancycoverflow;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
|
||||
|
||||
public abstract class FancyCoverFlowAdapter extends BaseAdapter {
|
||||
|
||||
// =============================================================================
|
||||
// Supertype overrides
|
||||
// =============================================================================
|
||||
|
||||
@Override
|
||||
public final View getView(int i, View reusableView, ViewGroup viewGroup) {
|
||||
FancyCoverFlow coverFlow = (FancyCoverFlow) viewGroup;
|
||||
|
||||
View wrappedView = null;
|
||||
FancyCoverFlowItemWrapper coverFlowItem;
|
||||
|
||||
if (reusableView != null) {
|
||||
coverFlowItem = (FancyCoverFlowItemWrapper) reusableView;
|
||||
wrappedView = coverFlowItem.getChildAt(0);
|
||||
coverFlowItem.removeAllViews();
|
||||
} else {
|
||||
coverFlowItem = new FancyCoverFlowItemWrapper(viewGroup.getContext());
|
||||
}
|
||||
|
||||
wrappedView = this.getCoverFlowItem(i, wrappedView, viewGroup);
|
||||
|
||||
if (wrappedView == null) {
|
||||
throw new NullPointerException("getCoverFlowItem() was expected to return a view, but null was returned.");
|
||||
}
|
||||
|
||||
final boolean isReflectionEnabled = coverFlow.isReflectionEnabled();
|
||||
coverFlowItem.setReflectionEnabled(isReflectionEnabled);
|
||||
|
||||
if(isReflectionEnabled) {
|
||||
coverFlowItem.setReflectionGap(coverFlow.getReflectionGap());
|
||||
coverFlowItem.setReflectionRatio(coverFlow.getReflectionRatio());
|
||||
}
|
||||
|
||||
|
||||
coverFlowItem.addView(wrappedView);
|
||||
coverFlowItem.setLayoutParams(wrappedView.getLayoutParams());
|
||||
|
||||
return coverFlowItem;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Abstract methods
|
||||
// =============================================================================
|
||||
|
||||
public abstract View getCoverFlowItem(int position, View reusableView, ViewGroup parent);
|
||||
}
|
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* Copyright 2013 David Schreiber
|
||||
* 2013 John Paul Nalog
|
||||
*
|
||||
* 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 at.technikum.mti.fancycoverflow;
|
||||
|
||||
import android.*;
|
||||
import android.R;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
/**
|
||||
* This class has only internal use (package scope).
|
||||
* <p/>
|
||||
* It is responsible for applying additional effects to each coverflow item, that can only be applied at view level
|
||||
* (e.g. color saturation).
|
||||
* <p/>
|
||||
* This is a ViewGroup by intention to enable child views in layouts to stay interactive (like buttons) though
|
||||
* transformed.
|
||||
* <p/>
|
||||
* Since this class is only used within the FancyCoverFlowAdapter it doesn't need to check if there are multiple
|
||||
* children or not (there can only be one at all times).
|
||||
*/
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
class FancyCoverFlowItemWrapper extends ViewGroup {
|
||||
|
||||
// =============================================================================
|
||||
// Private members
|
||||
// =============================================================================
|
||||
|
||||
private float saturation;
|
||||
|
||||
private boolean isReflectionEnabled = false;
|
||||
|
||||
private float imageReflectionRatio;
|
||||
|
||||
private int reflectionGap;
|
||||
|
||||
private float originalScaledownFactor;
|
||||
|
||||
/**
|
||||
* This is a matrix to apply color filters (like saturation) to the wrapped view.
|
||||
*/
|
||||
private ColorMatrix colorMatrix;
|
||||
|
||||
/**
|
||||
* This paint is used to draw the wrapped view including any filters.
|
||||
*/
|
||||
private Paint paint;
|
||||
|
||||
/**
|
||||
* This is a cache holding the wrapped view's visual representation.
|
||||
*/
|
||||
private Bitmap wrappedViewBitmap;
|
||||
|
||||
/**
|
||||
* This canvas is used to let the wrapped view draw it's content.
|
||||
*/
|
||||
private Canvas wrappedViewDrawingCanvas;
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// Constructor
|
||||
// =============================================================================
|
||||
|
||||
public FancyCoverFlowItemWrapper(Context context) {
|
||||
super(context);
|
||||
this.init();
|
||||
}
|
||||
|
||||
public FancyCoverFlowItemWrapper(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
this.init();
|
||||
}
|
||||
|
||||
public FancyCoverFlowItemWrapper(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
this.init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
this.paint = new Paint();
|
||||
this.colorMatrix = new ColorMatrix();
|
||||
// TODO: Define a default value for saturation inside an XML.
|
||||
this.setSaturation(1);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Getters / Setters
|
||||
// =============================================================================
|
||||
|
||||
void setReflectionEnabled(boolean hasReflection) {
|
||||
if (hasReflection != this.isReflectionEnabled) {
|
||||
this.isReflectionEnabled = hasReflection;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
// Turn off hardware acceleration if necessary (reflections won't support it).
|
||||
this.setLayerType(hasReflection ? View.LAYER_TYPE_SOFTWARE : View.LAYER_TYPE_HARDWARE, null);
|
||||
}
|
||||
|
||||
this.remeasureChildren();
|
||||
}
|
||||
}
|
||||
|
||||
void setReflectionRatio(float imageReflectionRatio) {
|
||||
if (imageReflectionRatio != this.imageReflectionRatio) {
|
||||
this.imageReflectionRatio = imageReflectionRatio;
|
||||
this.remeasureChildren();
|
||||
}
|
||||
}
|
||||
|
||||
void setReflectionGap(int reflectionGap) {
|
||||
if (reflectionGap != this.reflectionGap) {
|
||||
this.reflectionGap = reflectionGap;
|
||||
this.remeasureChildren();
|
||||
}
|
||||
}
|
||||
|
||||
public void setSaturation(float saturation) {
|
||||
if (saturation != this.saturation) {
|
||||
this.saturation = saturation;
|
||||
this.colorMatrix.setSaturation(saturation);
|
||||
this.paint.setColorFilter(new ColorMatrixColorFilter(this.colorMatrix));
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Supertype overrides
|
||||
// =============================================================================
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
this.remeasureChildren();
|
||||
|
||||
// If we have reflection enabled, the original image is scaled down and a reflection is added beneath. Thus,
|
||||
// while maintaining the same height the width decreases and we need to adjust measured width.
|
||||
// WARNING: This is a hack because we do not obey the EXACTLY MeasureSpec mode that we will get mostly.
|
||||
if (this.isReflectionEnabled) {
|
||||
this.setMeasuredDimension((int) (this.getMeasuredWidth() * this.originalScaledownFactor), this.getMeasuredHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("DrawAllocation")
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
if (changed) {
|
||||
int measuredWidth = this.getMeasuredWidth();
|
||||
int measuredHeight = this.getMeasuredHeight();
|
||||
|
||||
if (this.wrappedViewBitmap == null || this.wrappedViewBitmap.getWidth() != measuredWidth || this.wrappedViewBitmap.getHeight() != measuredHeight) {
|
||||
this.wrappedViewBitmap = Bitmap.createBitmap(measuredWidth, measuredHeight, Bitmap.Config.ARGB_8888);
|
||||
this.wrappedViewDrawingCanvas = new Canvas(this.wrappedViewBitmap);
|
||||
}
|
||||
|
||||
View child = getChildAt(0);
|
||||
int childWidth = child.getMeasuredWidth();
|
||||
int childHeight = child.getMeasuredHeight();
|
||||
int childLeft = (measuredWidth - childWidth) / 2;
|
||||
int childRight = measuredWidth - childLeft;
|
||||
child.layout(childLeft, 0, childRight, childHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
View childView = getChildAt(0);
|
||||
|
||||
if (childView != null) {
|
||||
// If on honeycomb or newer, cache the view.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
if (childView.isDirty()) {
|
||||
childView.draw(this.wrappedViewDrawingCanvas);
|
||||
|
||||
if (this.isReflectionEnabled) {
|
||||
this.createReflectedImages();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
childView.draw(this.wrappedViewDrawingCanvas);
|
||||
}
|
||||
}
|
||||
|
||||
canvas.drawBitmap(this.wrappedViewBitmap, (this.getWidth() - childView.getWidth()) / 2, 0, paint);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Methods
|
||||
// =============================================================================
|
||||
|
||||
private void remeasureChildren() {
|
||||
View child = this.getChildAt(0);
|
||||
|
||||
if (child != null) {
|
||||
// When reflection is enabled calculate proportional scale down factor.
|
||||
final int originalChildHeight = this.getMeasuredHeight();
|
||||
this.originalScaledownFactor = this.isReflectionEnabled ? (originalChildHeight * (1 - this.imageReflectionRatio) - reflectionGap) / originalChildHeight : 1.0f;
|
||||
final int childHeight = (int) (this.originalScaledownFactor * originalChildHeight);
|
||||
final int childWidth = (int) (this.originalScaledownFactor * getMeasuredWidth());
|
||||
|
||||
int heightSpec = MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.AT_MOST);
|
||||
int widthSpec = MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST);
|
||||
this.getChildAt(0).measure(widthSpec, heightSpec);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the reflected images.
|
||||
*
|
||||
* @return true, if successful
|
||||
*/
|
||||
private void createReflectedImages() {
|
||||
|
||||
final int width = this.wrappedViewBitmap.getWidth();
|
||||
final int height = this.wrappedViewBitmap.getHeight();
|
||||
|
||||
|
||||
final Matrix matrix = new Matrix();
|
||||
matrix.postScale(1, -1);
|
||||
|
||||
|
||||
final int scaledDownHeight = (int) (height * originalScaledownFactor);
|
||||
final int invertedHeight = height - scaledDownHeight - reflectionGap;
|
||||
final int invertedBitmapSourceTop = scaledDownHeight - invertedHeight;
|
||||
final Bitmap invertedBitmap = Bitmap.createBitmap(this.wrappedViewBitmap, 0, invertedBitmapSourceTop, width, invertedHeight, matrix, true);
|
||||
|
||||
this.wrappedViewDrawingCanvas.drawBitmap(invertedBitmap, 0, scaledDownHeight + reflectionGap, null);
|
||||
|
||||
final Paint paint = new Paint();
|
||||
final LinearGradient shader = new LinearGradient(0, height * imageReflectionRatio + reflectionGap, 0, height, 0x70ffffff, 0x00ffffff, Shader.TileMode.CLAMP);
|
||||
paint.setShader(shader);
|
||||
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
|
||||
this.wrappedViewDrawingCanvas.drawRect(0, height * (1 - imageReflectionRatio), width, height, paint);
|
||||
}
|
||||
}
|
|
@ -8,16 +8,17 @@ import android.app.Activity;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Environment;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView.ScaleType;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.TextView;
|
||||
import at.technikum.mti.fancycoverflow.FancyCoverFlow;
|
||||
|
||||
import com.reicast.emulator.GL2JNIActivity;
|
||||
import com.reicast.emulator.GL2JNINative;
|
||||
|
@ -124,47 +125,48 @@ public class OnScreenMenu {
|
|||
super(c);
|
||||
setBackgroundDrawable(null);
|
||||
int p = getPixelsFromDp(72, mContext);
|
||||
LayoutParams debugParams = new LayoutParams(p, p);
|
||||
LayoutParams debugParams = new LayoutParams(LayoutParams.WRAP_CONTENT, p);
|
||||
|
||||
LinearLayout hlay = new LinearLayout(mContext);
|
||||
|
||||
hlay.setOrientation(LinearLayout.HORIZONTAL);
|
||||
// hlay.setOrientation(LinearLayout.HORIZONTAL);
|
||||
hlay.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
hlay.addView(addbut(R.drawable.up, new OnClickListener() {
|
||||
hlay.addView(addbut(R.drawable.up, "Back", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
removePopUp(DebugPopup.this);
|
||||
}
|
||||
}), debugParams);
|
||||
|
||||
hlay.addView(addbut(R.drawable.clear_cache, new OnClickListener() {
|
||||
hlay.addView(addbut(R.drawable.clear_cache, "Clear Cache", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
JNIdc.send(0, 0); // Killing texture cache
|
||||
dismiss();
|
||||
}
|
||||
}), debugParams);
|
||||
|
||||
hlay.addView(addbut(R.drawable.profiler, new OnClickListener() {
|
||||
hlay.addView(addbut(R.drawable.profiler, "Profiler", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
JNIdc.send(1, 3000); // sample_Start(param);
|
||||
dismiss();
|
||||
}
|
||||
}), debugParams);
|
||||
|
||||
hlay.addView(addbut(R.drawable.profiler, new OnClickListener() {
|
||||
hlay.addView(addbut(R.drawable.profiler, "Profiler", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
JNIdc.send(1, 0); // sample_Start(param);
|
||||
dismiss();
|
||||
}
|
||||
}), debugParams);
|
||||
|
||||
hlay.addView(addbut(R.drawable.print_stats, new OnClickListener() {
|
||||
hlay.addView(addbut(R.drawable.print_stats, "Print Stats", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
JNIdc.send(0, 2);
|
||||
dismiss(); // print_stats=true;
|
||||
}
|
||||
}), debugParams);
|
||||
|
||||
hlay.addView(addbut(R.drawable.close, new OnClickListener() {
|
||||
hlay.addView(addbut(R.drawable.close, "Exit", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
popups.remove(DebugPopup.this);
|
||||
dismiss();
|
||||
|
@ -200,13 +202,14 @@ public class OnScreenMenu {
|
|||
super(c);
|
||||
setBackgroundDrawable(null);
|
||||
int p = getPixelsFromDp(72, mContext);
|
||||
LayoutParams configParams = new LayoutParams(p, p);
|
||||
LayoutParams configParams = new LayoutParams(LayoutParams.WRAP_CONTENT, p);
|
||||
|
||||
LinearLayout hlay = new LinearLayout(mContext);
|
||||
|
||||
hlay.setOrientation(LinearLayout.HORIZONTAL);
|
||||
// hlay.setOrientation(LinearLayout.HORIZONTAL);
|
||||
hlay.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
View up = addbut(R.drawable.up, new OnClickListener() {
|
||||
View up = addbut(R.drawable.up, "Back", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
removePopUp(ConfigPopup.this);
|
||||
}
|
||||
|
@ -214,30 +217,33 @@ public class OnScreenMenu {
|
|||
hlay.addView(up, configParams);
|
||||
menuItems.add(up);
|
||||
|
||||
fullscreen = addbut(R.drawable.widescreen, new OnClickListener() {
|
||||
fullscreen = addbut(R.drawable.widescreen, "Widescreen", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (screen) {
|
||||
JNIdc.widescreen(0);
|
||||
screen = false;
|
||||
((ImageButton) fullscreen)
|
||||
.setImageResource(R.drawable.widescreen);
|
||||
// ((ImageButton) fullscreen)
|
||||
// .setImageResource(R.drawable.widescreen);
|
||||
modbut(fullscreen, R.drawable.widescreen);
|
||||
} else {
|
||||
JNIdc.widescreen(1);
|
||||
screen = true;
|
||||
((ImageButton) fullscreen)
|
||||
.setImageResource(R.drawable.normal_view);
|
||||
// ((ImageButton) fullscreen)
|
||||
// .setImageResource(R.drawable.normal_view);
|
||||
modbut(fullscreen, R.drawable.normal_view);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (screen) {
|
||||
((ImageButton) fullscreen)
|
||||
.setImageResource(R.drawable.normal_view);
|
||||
// ((ImageButton) fullscreen)
|
||||
// .setImageResource(R.drawable.normal_view);
|
||||
modbut(fullscreen, R.drawable.normal_view);
|
||||
|
||||
}
|
||||
hlay.addView(fullscreen, params);
|
||||
menuItems.add(fullscreen);
|
||||
|
||||
fdown = addbut(R.drawable.frames_down, new OnClickListener() {
|
||||
fdown = addbut(R.drawable.frames_down, "Frameskip -", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (frames > 0) {
|
||||
frames--;
|
||||
|
@ -246,7 +252,7 @@ public class OnScreenMenu {
|
|||
enableState(fdown, fup);
|
||||
}
|
||||
});
|
||||
fup = addbut(R.drawable.frames_up, new OnClickListener() {
|
||||
fup = addbut(R.drawable.frames_up, "Frameskip +", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (frames < 5) {
|
||||
frames++;
|
||||
|
@ -262,30 +268,33 @@ public class OnScreenMenu {
|
|||
menuItems.add(fup);
|
||||
enableState(fdown, fup);
|
||||
|
||||
framelimit = addbut(R.drawable.frames_limit_on,
|
||||
framelimit = addbut(R.drawable.frames_limit_on, "Frame Limiter",
|
||||
new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (limit) {
|
||||
JNIdc.limitfps(0);
|
||||
limit = false;
|
||||
((ImageButton) framelimit)
|
||||
.setImageResource(R.drawable.frames_limit_on);
|
||||
// ((ImageButton) framelimit)
|
||||
// .setImageResource(R.drawable.frames_limit_on);
|
||||
modbut(framelimit, R.drawable.frames_limit_on);
|
||||
} else {
|
||||
JNIdc.limitfps(1);
|
||||
limit = true;
|
||||
((ImageButton) framelimit)
|
||||
.setImageResource(R.drawable.frames_limit_off);
|
||||
// ((ImageButton) framelimit)
|
||||
// .setImageResource(R.drawable.frames_limit_off);
|
||||
modbut(framelimit, R.drawable.frames_limit_off);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (limit) {
|
||||
((ImageButton) framelimit)
|
||||
.setImageResource(R.drawable.frames_limit_off);
|
||||
// ((ImageButton) framelimit)
|
||||
// .setImageResource(R.drawable.frames_limit_off);
|
||||
modbut(framelimit, R.drawable.frames_limit_off);
|
||||
}
|
||||
hlay.addView(framelimit, params);
|
||||
menuItems.add(framelimit);
|
||||
|
||||
audiosetting = addbut(R.drawable.enable_sound,
|
||||
audiosetting = addbut(R.drawable.enable_sound, "Emu Sound",
|
||||
new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (audio) {
|
||||
|
@ -298,8 +307,9 @@ public class OnScreenMenu {
|
|||
.audioDisable(true);
|
||||
}
|
||||
audio = false;
|
||||
((ImageButton) audiosetting)
|
||||
.setImageResource(R.drawable.enable_sound);
|
||||
// ((ImageButton) audiosetting)
|
||||
// .setImageResource(R.drawable.enable_sound);
|
||||
modbut(audiosetting, R.drawable.enable_sound);
|
||||
} else {
|
||||
if (mContext instanceof GL2JNINative) {
|
||||
((GL2JNINative) mContext).mView
|
||||
|
@ -310,14 +320,16 @@ public class OnScreenMenu {
|
|||
.audioDisable(false);
|
||||
}
|
||||
audio = true;
|
||||
((ImageButton) audiosetting)
|
||||
.setImageResource(R.drawable.mute_sound);
|
||||
// ((ImageButton) audiosetting)
|
||||
// .setImageResource(R.drawable.mute_sound);
|
||||
modbut(audiosetting, R.drawable.mute_sound);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (audio) {
|
||||
((ImageButton) audiosetting)
|
||||
.setImageResource(R.drawable.mute_sound);
|
||||
// ((ImageButton) audiosetting)
|
||||
// .setImageResource(R.drawable.mute_sound);
|
||||
modbut(audiosetting, R.drawable.mute_sound);
|
||||
}
|
||||
if (!masteraudio) {
|
||||
audiosetting.setEnabled(false);
|
||||
|
@ -325,7 +337,7 @@ public class OnScreenMenu {
|
|||
hlay.addView(audiosetting, params);
|
||||
menuItems.add(audiosetting);
|
||||
|
||||
fastforward = addbut(R.drawable.star, new OnClickListener() {
|
||||
fastforward = addbut(R.drawable.star, "Turbo", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (boosted) {
|
||||
if (mContext instanceof GL2JNINative) {
|
||||
|
@ -350,8 +362,9 @@ public class OnScreenMenu {
|
|||
.fastForward(false);
|
||||
}
|
||||
boosted = false;
|
||||
((ImageButton) fastforward)
|
||||
.setImageResource(R.drawable.star);
|
||||
// ((ImageButton) fastforward)
|
||||
// .setImageResource(R.drawable.star);
|
||||
modbut(fastforward, R.drawable.star);
|
||||
} else {
|
||||
if (mContext instanceof GL2JNINative) {
|
||||
((GL2JNINative) mContext).mView.audioDisable(true);
|
||||
|
@ -374,18 +387,20 @@ public class OnScreenMenu {
|
|||
((GL2JNIActivity) mContext).mView.fastForward(true);
|
||||
}
|
||||
boosted = true;
|
||||
((ImageButton) fastforward)
|
||||
.setImageResource(R.drawable.reset);
|
||||
// ((ImageButton) fastforward)
|
||||
// .setImageResource(R.drawable.reset);
|
||||
modbut(fastforward, R.drawable.reset);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (boosted) {
|
||||
((ImageButton) fastforward).setImageResource(R.drawable.reset);
|
||||
// ((ImageButton) fastforward).setImageResource(R.drawable.reset);
|
||||
modbut(fastforward, R.drawable.reset);
|
||||
}
|
||||
hlay.addView(fastforward, params);
|
||||
menuItems.add(fastforward);
|
||||
|
||||
View close = addbut(R.drawable.close, new OnClickListener() {
|
||||
View close = addbut(R.drawable.close, "Exit", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
popups.remove(ConfigPopup.this);
|
||||
dismiss();
|
||||
|
@ -450,16 +465,38 @@ public class OnScreenMenu {
|
|||
return vmuLcd;
|
||||
}
|
||||
|
||||
View addbut(int x, OnClickListener ocl) {
|
||||
ImageButton but = new ImageButton(mContext);
|
||||
|
||||
but.setImageResource(x);
|
||||
but.setScaleType(ScaleType.FIT_CENTER);
|
||||
View addbut(int x, String l, OnClickListener ocl) {
|
||||
// ImageButton but = new ImageButton(mContext);
|
||||
//
|
||||
// but.setImageResource(x);
|
||||
// but.setScaleType(ScaleType.FIT_CENTER);
|
||||
// but.setOnClickListener(ocl);
|
||||
|
||||
Button but = new Button(mContext);
|
||||
Drawable image = mContext.getResources().getDrawable(x);
|
||||
image.setBounds(0, 0, 72, 72);
|
||||
but.setCompoundDrawables(image, null, null, null);
|
||||
but.setText(l);
|
||||
but.setOnClickListener(ocl);
|
||||
|
||||
return but;
|
||||
}
|
||||
|
||||
void modbut (View button, int x) {
|
||||
Button but = (Button) button;
|
||||
Drawable image = mContext.getResources().getDrawable(x);
|
||||
image.setBounds(0, 0, 72, 72);
|
||||
but.setCompoundDrawables(image, null, null, null);
|
||||
}
|
||||
|
||||
void showXMBMenu() {
|
||||
FancyCoverFlow fancyCoverFlow = new FancyCoverFlow(mContext);
|
||||
fancyCoverFlow.setMaxRotation(45);
|
||||
fancyCoverFlow.setUnselectedAlpha(0.3f);
|
||||
fancyCoverFlow.setUnselectedSaturation(0.0f);
|
||||
fancyCoverFlow.setUnselectedScale(0.4f);
|
||||
}
|
||||
|
||||
public class VmuPopup extends PopupWindow {
|
||||
LayoutParams vparams;
|
||||
LinearLayout vlay;
|
||||
|
@ -490,9 +527,10 @@ public class OnScreenMenu {
|
|||
super(c);
|
||||
setBackgroundDrawable(null);
|
||||
int p = getPixelsFromDp(72, mContext);
|
||||
params = new LayoutParams(p, p);
|
||||
params = new LayoutParams(LayoutParams.WRAP_CONTENT, p);
|
||||
hlay = new LinearLayout(mContext);
|
||||
hlay.setOrientation(LinearLayout.HORIZONTAL);
|
||||
// hlay.setOrientation(LinearLayout.HORIZONTAL);
|
||||
hlay.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
int vpX = getPixelsFromDp(72, mContext);
|
||||
int vpY = getPixelsFromDp(52, mContext);
|
||||
|
@ -503,21 +541,21 @@ public class OnScreenMenu {
|
|||
vmuParams.rightMargin = 4;
|
||||
hlay.addView(vmuLcd, vmuParams);
|
||||
|
||||
hlay.addView(addbut(R.drawable.up, new OnClickListener() {
|
||||
hlay.addView(addbut(R.drawable.up, "Back", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
popups.remove(MainPopup.this);
|
||||
dismiss();
|
||||
}
|
||||
}), params);
|
||||
|
||||
hlay.addView(addbut(R.drawable.vmu_swap, new OnClickListener() {
|
||||
hlay.addView(addbut(R.drawable.vmu_swap, "VMU Swap", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
JNIdc.vmuSwap();
|
||||
dismiss();
|
||||
}
|
||||
}), params);
|
||||
|
||||
rsticksetting = addbut(R.drawable.toggle_a_b,
|
||||
rsticksetting = addbut(R.drawable.toggle_a_b, "Right Stick",
|
||||
new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (prefs
|
||||
|
@ -525,25 +563,28 @@ public class OnScreenMenu {
|
|||
prefs.edit()
|
||||
.putBoolean(Gamepad.pref_js_rbuttons,
|
||||
false).commit();
|
||||
((ImageButton) rsticksetting)
|
||||
.setImageResource(R.drawable.toggle_a_b);
|
||||
// ((ImageButton) rsticksetting)
|
||||
// .setImageResource(R.drawable.toggle_a_b);
|
||||
modbut(rsticksetting, R.drawable.toggle_a_b);
|
||||
} else {
|
||||
prefs.edit()
|
||||
.putBoolean(Gamepad.pref_js_rbuttons,
|
||||
true).commit();
|
||||
((ImageButton) rsticksetting)
|
||||
.setImageResource(R.drawable.toggle_r_l);
|
||||
// ((ImageButton) rsticksetting)
|
||||
// .setImageResource(R.drawable.toggle_r_l);
|
||||
modbut(rsticksetting, R.drawable.toggle_r_l);
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
if (prefs.getBoolean(Gamepad.pref_js_rbuttons, true)) {
|
||||
((ImageButton) rsticksetting)
|
||||
.setImageResource(R.drawable.toggle_r_l);
|
||||
// ((ImageButton) rsticksetting)
|
||||
// .setImageResource(R.drawable.toggle_r_l);
|
||||
modbut(rsticksetting, R.drawable.toggle_r_l);
|
||||
}
|
||||
hlay.addView(rsticksetting, params);
|
||||
|
||||
hlay.addView(addbut(R.drawable.config, new OnClickListener() {
|
||||
hlay.addView(addbut(R.drawable.config, "Options", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
displayConfigPopup(MainPopup.this);
|
||||
popups.remove(MainPopup.this);
|
||||
|
@ -551,7 +592,7 @@ public class OnScreenMenu {
|
|||
}
|
||||
}), params);
|
||||
|
||||
hlay.addView(addbut(R.drawable.disk_unknown, new OnClickListener() {
|
||||
hlay.addView(addbut(R.drawable.disk_unknown, "Debugging", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
displayDebugPopup(MainPopup.this);
|
||||
popups.remove(MainPopup.this);
|
||||
|
@ -559,7 +600,7 @@ public class OnScreenMenu {
|
|||
}
|
||||
}), params);
|
||||
|
||||
hlay.addView(addbut(R.drawable.print_stats, new OnClickListener() {
|
||||
hlay.addView(addbut(R.drawable.print_stats, "Screenshot", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
// screenshot
|
||||
if (mContext instanceof GL2JNINative) {
|
||||
|
@ -573,7 +614,7 @@ public class OnScreenMenu {
|
|||
}
|
||||
}), params);
|
||||
|
||||
hlay.addView(addbut(R.drawable.close, new OnClickListener() {
|
||||
hlay.addView(addbut(R.drawable.close, "Exit", new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
Intent inte = new Intent(mContext, MainActivity.class);
|
||||
mContext.startActivity(inte);
|
||||
|
|
Loading…
Reference in New Issue