Allow the song info to be shown below the cover instead of on top of it
The complexity of the cover view drawing routines is getting a bit ridiculous..
This commit is contained in:
parent
124780de98
commit
9e8bc71904
@ -7,6 +7,7 @@
|
||||
<string name="settings">Preferences</string>
|
||||
<string name="library">Choose Songs</string>
|
||||
<string name="quit">Stop and Exit</string>
|
||||
<string name="display_mode">Display Mode</string>
|
||||
|
||||
<!-- Widgets -->
|
||||
<string name="starting">Starting up...</string>
|
||||
|
@ -29,7 +29,7 @@ import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Region;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
@ -42,7 +42,7 @@ import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.widget.Scroller;
|
||||
|
||||
public class CoverView extends View {
|
||||
public final class CoverView extends View {
|
||||
private static final int STORE_SIZE = 3;
|
||||
private final int SNAP_VELOCITY;
|
||||
|
||||
@ -53,6 +53,8 @@ public class CoverView extends View {
|
||||
private float mStartY;
|
||||
private IPlaybackService mService;
|
||||
|
||||
private boolean mSeparateInfo;
|
||||
|
||||
Song[] mSongs = new Song[3];
|
||||
private Bitmap[] mBitmaps = new Bitmap[3];
|
||||
|
||||
@ -66,6 +68,16 @@ public class CoverView extends View {
|
||||
SNAP_VELOCITY = ViewConfiguration.get(context).getScaledMinimumFlingVelocity();
|
||||
}
|
||||
|
||||
public boolean hasSeparateInfo()
|
||||
{
|
||||
return mSeparateInfo;
|
||||
}
|
||||
|
||||
public void setSeparateInfo(boolean separate)
|
||||
{
|
||||
mSeparateInfo = separate;
|
||||
}
|
||||
|
||||
public void setPlaybackService(IPlaybackService service)
|
||||
{
|
||||
try {
|
||||
@ -78,9 +90,11 @@ public class CoverView extends View {
|
||||
|
||||
private static void drawText(Canvas canvas, String text, float left, float top, float width, float maxWidth, Paint paint)
|
||||
{
|
||||
canvas.save();
|
||||
float offset = Math.max(0, maxWidth - width) / 2;
|
||||
canvas.clipRect(left, top, left + maxWidth, top + paint.getTextSize() * 2, Region.Op.REPLACE);
|
||||
canvas.clipRect(left, top, left + maxWidth, top + paint.getTextSize() * 2);
|
||||
canvas.drawText(text, left + offset, top - paint.ascent(), paint);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
private static RectF centerRect(float maxWidth, float maxHeight, float width, float height)
|
||||
@ -149,7 +163,7 @@ public class CoverView extends View {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public Bitmap createBitmap(Song song, int width, int height)
|
||||
private Bitmap createOverlappingBitmap(Song song, int width, int height)
|
||||
{
|
||||
if (song == null || width < 1 || height < 1)
|
||||
return null;
|
||||
@ -231,10 +245,108 @@ public class CoverView extends View {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
private Bitmap createSeparatedBitmap(Song song, int width, int height)
|
||||
{
|
||||
if (song == null || width < 1 || height < 1)
|
||||
return null;
|
||||
|
||||
boolean horizontal = width > height;
|
||||
|
||||
Paint paint = new Paint();
|
||||
paint.setAntiAlias(true);
|
||||
|
||||
String title = song.title == null ? "" : song.title;
|
||||
String album = song.album == null ? "" : song.album;
|
||||
String artist = song.artist == null ? "" : song.artist;
|
||||
Bitmap cover = song.coverPath == null ? null : BitmapFactory.decodeFile(song.coverPath);
|
||||
|
||||
float coverWidth;
|
||||
float coverHeight;
|
||||
|
||||
if (cover == null) {
|
||||
coverWidth = 0;
|
||||
coverHeight = 0;
|
||||
} else {
|
||||
coverWidth = cover.getWidth();
|
||||
coverHeight = cover.getHeight();
|
||||
|
||||
float drawableAspectRatio = coverHeight / coverWidth;
|
||||
float viewAspectRatio = (float) height / width;
|
||||
float scale = drawableAspectRatio > viewAspectRatio ? height / coverWidth
|
||||
: width / coverHeight;
|
||||
|
||||
coverWidth *= scale;
|
||||
coverHeight *= scale;
|
||||
}
|
||||
|
||||
DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
|
||||
float textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14, metrics);
|
||||
float padding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, metrics);
|
||||
|
||||
paint.setTextSize(textSize);
|
||||
float titleWidth = paint.measureText(title);
|
||||
float albumWidth = paint.measureText(album);
|
||||
float artistWidth = paint.measureText(artist);
|
||||
|
||||
float maxBoxWidth = horizontal ? width - coverWidth : width;
|
||||
float maxBoxHeight = horizontal ? height : height - coverHeight;
|
||||
float boxWidth = Math.min(maxBoxWidth, textSize + Math.max(titleWidth, Math.max(artistWidth, albumWidth)) + padding * 3);
|
||||
float boxHeight = Math.min(maxBoxHeight, textSize * 3 + padding * 4);
|
||||
|
||||
int bitmapWidth = (int)(horizontal ? coverWidth + boxWidth : Math.max(coverWidth, boxWidth));
|
||||
int bitmapHeight = (int)(horizontal ? Math.max(coverHeight, boxHeight) : coverHeight + boxHeight);
|
||||
|
||||
Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.RGB_565);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
|
||||
if (cover != null) {
|
||||
RectF rect = new RectF(0, 0, coverWidth, coverHeight);
|
||||
canvas.drawBitmap(cover, null, rect, paint);
|
||||
cover.recycle();
|
||||
cover = null;
|
||||
}
|
||||
|
||||
Drawable drawable;
|
||||
float top = padding;
|
||||
float left = padding;
|
||||
|
||||
if (horizontal) {
|
||||
top = (height - boxHeight) / 2;
|
||||
left += coverWidth;
|
||||
} else {
|
||||
top += coverHeight;
|
||||
}
|
||||
|
||||
float maxWidth = boxWidth - padding * 3 - textSize;
|
||||
paint.setARGB(255, 255, 255, 255);
|
||||
|
||||
drawable = getResources().getDrawable(R.drawable.tab_songs_selected);
|
||||
drawable.setBounds((int)left, (int)top, (int)(left + textSize), (int)(top + textSize));
|
||||
drawable.draw(canvas);
|
||||
drawText(canvas, title, left + padding + textSize, top, maxWidth, maxWidth, paint);
|
||||
top += textSize + padding;
|
||||
|
||||
drawable = getResources().getDrawable(R.drawable.tab_albums_selected);
|
||||
drawable.setBounds((int)left, (int)top, (int)(left + textSize), (int)(top + textSize));
|
||||
drawable.draw(canvas);
|
||||
drawText(canvas, album, left + padding + textSize, top, maxWidth, maxWidth, paint);
|
||||
top += textSize + padding;
|
||||
|
||||
drawable = getResources().getDrawable(R.drawable.tab_artists_selected);
|
||||
drawable.setBounds((int)left, (int)top, (int)(left + textSize), (int)(top + textSize));
|
||||
drawable.draw(canvas);
|
||||
drawText(canvas, artist, left + padding + textSize, top, maxWidth, maxWidth, paint);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
private void createBitmap(int i)
|
||||
{
|
||||
Bitmap oldBitmap = mBitmaps[i];
|
||||
mBitmaps[i] = createBitmap(mSongs[i], getWidth(), getHeight());
|
||||
if (mSeparateInfo)
|
||||
mBitmaps[i] = createSeparatedBitmap(mSongs[i], getWidth(), getHeight());
|
||||
else
|
||||
mBitmaps[i] = createOverlappingBitmap(mSongs[i], getWidth(), getHeight());
|
||||
if (oldBitmap != null)
|
||||
oldBitmap.recycle();
|
||||
}
|
||||
@ -296,14 +408,26 @@ public class CoverView extends View {
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private void regenerateBitmaps()
|
||||
{
|
||||
for (int i = STORE_SIZE; --i != -1; )
|
||||
createBitmap(i);
|
||||
}
|
||||
|
||||
public void toggleDisplayMode()
|
||||
{
|
||||
mSeparateInfo = !mSeparateInfo;
|
||||
regenerateBitmaps();
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight)
|
||||
{
|
||||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
for (int i = STORE_SIZE; --i != -1; )
|
||||
createBitmap(i);
|
||||
regenerateBitmaps();
|
||||
reset();
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,7 @@ public class FullPlaybackActivity extends PlaybackActivity implements View.OnCli
|
||||
private static final int SONG_SELECTOR = 8;
|
||||
|
||||
private static final int MENU_QUIT = 0;
|
||||
private static final int MENU_DISPLAY = 1;
|
||||
private static final int MENU_PREFS = 2;
|
||||
private static final int MENU_LIBRARY = 3;
|
||||
|
||||
@ -70,16 +71,15 @@ public class FullPlaybackActivity extends PlaybackActivity implements View.OnCli
|
||||
{
|
||||
super.onCreate(icicle);
|
||||
|
||||
if (icicle == null) {
|
||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
if (settings.getBoolean("selector_on_startup", false))
|
||||
showDialog(SONG_SELECTOR);
|
||||
}
|
||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
if (icicle == null && settings.getBoolean("selector_on_startup", false))
|
||||
showDialog(SONG_SELECTOR);
|
||||
|
||||
setContentView(R.layout.full_playback);
|
||||
|
||||
mCoverView = (CoverView)findViewById(R.id.cover_view);
|
||||
mCoverView.setOnClickListener(this);
|
||||
mCoverView.setSeparateInfo(settings.getBoolean("separate_info", false));
|
||||
|
||||
mControlsTop = findViewById(R.id.controls_top);
|
||||
mControlsBottom = findViewById(R.id.controls_bottom);
|
||||
@ -101,6 +101,17 @@ public class FullPlaybackActivity extends PlaybackActivity implements View.OnCli
|
||||
mSeekBar.setOnFocusChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy()
|
||||
{
|
||||
super.onDestroy();
|
||||
|
||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.putBoolean("separate_info", mCoverView.hasSeparateInfo());
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setState(int state)
|
||||
{
|
||||
@ -178,6 +189,7 @@ public class FullPlaybackActivity extends PlaybackActivity implements View.OnCli
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
menu.add(0, MENU_DISPLAY, 0, R.string.display_mode).setIcon(android.R.drawable.ic_menu_gallery);
|
||||
menu.add(0, MENU_LIBRARY, 0, R.string.library).setIcon(android.R.drawable.ic_menu_add);
|
||||
menu.add(0, MENU_PREFS, 0, R.string.settings).setIcon(android.R.drawable.ic_menu_preferences);
|
||||
menu.add(0, MENU_QUIT, 0, R.string.quit).setIcon(android.R.drawable.ic_menu_close_clear_cancel);
|
||||
@ -204,6 +216,9 @@ public class FullPlaybackActivity extends PlaybackActivity implements View.OnCli
|
||||
case MENU_LIBRARY:
|
||||
showDialog(SONG_SELECTOR);
|
||||
break;
|
||||
case MENU_DISPLAY:
|
||||
mCoverView.toggleDisplayMode();
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user