[Android] The emulation overlay now sets the button positions based upon the locations chosen in the input overlay configuration settings. Documented the hell out of how the initialization of the Drawables works inside InputOverlay.java.

Also made the use of InputOverlayItem.java obsolete. So this is now removed.
This commit is contained in:
Lioncash 2013-10-25 20:34:38 -04:00
parent 88c797a9c0
commit c8cf71c913
4 changed files with 105 additions and 114 deletions

View File

@ -5,7 +5,7 @@
android:layout_height="fill_parent" >
<org.dolphinemu.dolphinemu.settings.input.InputOverlayConfigButton
android:id="@+id/buttonA"
android:id="@+id/button_a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
@ -13,20 +13,20 @@
android:background="@drawable/button_a" />
<org.dolphinemu.dolphinemu.settings.input.InputOverlayConfigButton
android:id="@+id/buttonB"
android:id="@+id/button_b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/buttonA"
android:layout_toRightOf="@+id/button_a"
android:background="@drawable/button_b" />
<org.dolphinemu.dolphinemu.settings.input.InputOverlayConfigButton
android:id="@+id/buttonStart"
android:id="@+id/button_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_toRightOf="@+id/buttonB"
android:layout_toRightOf="@+id/button_b"
android:background="@drawable/button_start" />
</RelativeLayout>

View File

@ -3,8 +3,14 @@ package org.dolphinemu.dolphinemu.emulation.overlay;
import java.util.HashSet;
import java.util.Set;
import org.dolphinemu.dolphinemu.R;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceView;
@ -17,7 +23,7 @@ import android.view.View.OnTouchListener;
*/
public final class InputOverlay extends SurfaceView implements OnTouchListener
{
private final Set<InputOverlayItem> overlayItems = new HashSet<InputOverlayItem>();
private final Set<BitmapDrawable> overlayItems = new HashSet<BitmapDrawable>();
/**
* Constructor
@ -29,6 +35,11 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
{
super(context, attrs);
// Add all the overlay items to the HashSet.
overlayItems.add(initializeOverlayDrawable(context, R.drawable.button_a));
overlayItems.add(initializeOverlayDrawable(context, R.drawable.button_b));
overlayItems.add(initializeOverlayDrawable(context, R.drawable.button_start));
// Force draw
setWillNotDraw(false);
@ -56,9 +67,74 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
{
super.onDraw(canvas);
for (InputOverlayItem item : overlayItems)
// Draw all overlay items.
for (BitmapDrawable item : overlayItems)
{
item.draw(canvas);
}
}
/**
* Initializes a drawable, given by resId, with all of the
* parameters set for it to be properly shown on the InputOverlay.
* <p>
* This works due to the way the X and Y coordinates are stored within
* the {@link SharedPreferences}.
* <p>
* In the input overlay configuration menu,
* once a touch event begins and then ends (ie. Organizing the buttons to one's own liking for the overlay).
* the X and Y coordinates of the button at the END of its touch event
* (when you remove your finger/stylus from the touchscreen) are then stored
* within a SharedPreferences instance so that those values can be retrieved here.
* <p>
* This has a few benefits over the conventional way of storing the values
* (ie. within the Dolphin ini file).
* <ul>
* <li>No native calls</li>
* <li>Keeps Android-only values inside the Android environment</li>
* </ul>
* <p>
* Technically no modifications should need to be performed on the returned
* BitmapDrawable. Simply add it to the HashSet of overlay items and wait
* for Android to call the onDraw method.
*
* @param context The current {@link Context}.
* @param resId The resource ID of the {@link BitmapDrawable} to get.
*
* @return A {@link BitmapDrawable} with the correct drawing bounds set.
*
*/
private static BitmapDrawable initializeOverlayDrawable(Context context, int resId)
{
// Resources handle for fetching the drawable, etc.
final Resources res = context.getResources();
// SharedPreference to retrieve the X and Y coordinates for the drawable.
final SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(context);
// Get the desired drawable.
BitmapDrawable drawable = (BitmapDrawable) res.getDrawable(resId);
// String ID of the drawable. This is what is passed into SharedPreferences
// to check whether or not a value has been set.
String drawableId = res.getResourceEntryName(resId);
// The X and Y coordinates of the drawable on the InputOverlay.
// These were set in the input overlay configuration menu.
int drawableX = (int) sPrefs.getFloat(drawableId+"-X", 0f);
int drawableY = (int) sPrefs.getFloat(drawableId+"-Y", 0f);
// Intrinsic width and height of the drawable.
// For any who may not know, intrinsic width/height
// are the original unmodified width and height of the image.
int intrinWidth = drawable.getIntrinsicWidth();
int intrinHeight = drawable.getIntrinsicHeight();
// Now set the bounds for the drawable.
// This will dictate where on the screen (and the what the size) of the drawable will be.
drawable.setBounds(drawableX, drawableY, drawableX+intrinWidth, drawableY+intrinHeight);
return drawable;
}
}

View File

@ -1,107 +0,0 @@
package org.dolphinemu.dolphinemu.emulation.overlay;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
/**
* Represents a drawable image for the {@link InputOverlay}
*/
public final class InputOverlayItem
{
// The image as a BitmapDrawable
private BitmapDrawable drawable;
// Width and height of the underlying image.
private int width;
private int height;
// X and Y coordinates to display this item at.
private int x;
private int y;
// Image scale factor.
private float scaleFactor = 1.0f;
// Rectangle that we draw this item to.
private Rect drawRect;
/**
* Constructor.
*
* @param res Reference to the app resources for fetching display metrics.
* @param resId Resource ID of the {@link BitmapDrawable} to encapsulate.
*/
public InputOverlayItem(Resources res, int resId)
{
// Idiot-proof the constructor.
if (res == null)
throw new IllegalArgumentException("res cannot be null");
// Everything is valid, decode the filename as a bitmap.
drawable = (BitmapDrawable) res.getDrawable(resId);
Bitmap image = drawable.getBitmap();
// Set width/height
width = image.getWidth();
height = image.getHeight();
// Initialize rectangle to zero width, height, x, and y.
drawRect = new Rect();
}
/**
* Constructor
*
* @param res Reference to the app resources for fetching display metrics.
* @param resId Resource ID of the {@link BitmapDrawable} to encapsulate.
* @param x X coordinate on the screen to place the control.
* @param y Y coordinate on the screen to place the control.
*/
public InputOverlayItem(Resources res, int resId, int x, int y)
{
this(res, resId);
setPosition(x, y);
}
/**
* Sets the position of this item on the screen.
*
* @param x New x-coordinate for this image.
* @param y New y-coordinate for this image.
*/
public void setPosition(int x, int y)
{
this.x = x;
this.y = y;
drawRect.set(x, y, x + (int)(width * scaleFactor), y + (int)(height * scaleFactor));
drawable.setBounds(drawRect);
}
/**
* Sets a new scaling factor for the current image.
*
* @param scaleFactor The new scaling factor. Note that 1.0 is normal size.
*/
public void setScaleFactor(float scaleFactor)
{
this.scaleFactor = scaleFactor;
// Adjust for the new scale factor.
setPosition(x, y);
}
/**
* Draws this item to a given canvas.
*
* @param canvas The canvas to draw this item to.
*/
public void draw(Canvas canvas)
{
drawable.draw(canvas);
}
}

View File

@ -7,6 +7,8 @@
package org.dolphinemu.dolphinemu.settings.input;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
@ -19,6 +21,9 @@ import android.widget.Button;
*/
public final class InputOverlayConfigButton extends Button implements OnTouchListener
{
// SharedPreferences instance that the button positions are cached to.
private final SharedPreferences sharedPrefs;
/**
* Constructor
*
@ -31,6 +36,9 @@ public final class InputOverlayConfigButton extends Button implements OnTouchLis
// Set the button as its own OnTouchListener.
setOnTouchListener(this);
// Get the SharedPreferences instance.
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
}
@Override
@ -45,6 +53,20 @@ public final class InputOverlayConfigButton extends Button implements OnTouchLis
setY(getY() + event.getY());
return true;
}
// Whenever the press event has ended
// is when we save all of the information.
case MotionEvent.ACTION_UP:
{
// String ID of this button.
String buttonId = getResources().getResourceEntryName(getId());
// Add the current X and Y positions of this button into SharedPreferences.
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putFloat(buttonId+"-X", getX());
editor.putFloat(buttonId+"-Y", getY());
editor.commit();
}
}
return false;