Add default cover for no info modes
The improves swiping: before, with no default cover, one just swiped a black screen with no scrolling feedback, which was rather unintuitive.
This commit is contained in:
parent
bb39b8677e
commit
cd847f4a93
BIN
orig/default_cover.svgz
Normal file
BIN
orig/default_cover.svgz
Normal file
Binary file not shown.
BIN
res/drawable-hdpi/default_cover.png
Normal file
BIN
res/drawable-hdpi/default_cover.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
BIN
res/drawable-mdpi/default_cover.png
Normal file
BIN
res/drawable-mdpi/default_cover.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
@ -136,15 +136,18 @@ public final class CoverBitmap {
|
||||
*/
|
||||
public static Bitmap createBitmap(Context context, int style, Song song, int width, int height, Bitmap bitmap)
|
||||
{
|
||||
if (song == null)
|
||||
return null;
|
||||
|
||||
switch (style) {
|
||||
case STYLE_OVERLAPPING_BOX:
|
||||
return createOverlappingBitmap(context, song, width, height, bitmap);
|
||||
case STYLE_INFO_BELOW:
|
||||
return createSeparatedBitmap(context, song, width, height, bitmap);
|
||||
case STYLE_NO_INFO:
|
||||
return createScaledBitmap(context, song, width, height, bitmap);
|
||||
return createScaledBitmap(song.getCover(context), width, height, bitmap);
|
||||
case STYLE_NO_INFO_ZOOMED:
|
||||
return createZoomedBitmap(context, song, width, height, bitmap);
|
||||
return createZoomedBitmap(song.getCover(context), width, height, bitmap);
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid bitmap type given: " + style);
|
||||
}
|
||||
@ -152,7 +155,7 @@ public final class CoverBitmap {
|
||||
|
||||
private static Bitmap createOverlappingBitmap(Context context, Song song, int width, int height, Bitmap bitmap)
|
||||
{
|
||||
if (song == null || width < 1 || height < 1)
|
||||
if (width < 1 || height < 1)
|
||||
return null;
|
||||
|
||||
if (TEXT_SIZE == -1)
|
||||
@ -246,7 +249,7 @@ public final class CoverBitmap {
|
||||
|
||||
private static Bitmap createSeparatedBitmap(Context context, Song song, int width, int height, Bitmap bitmap)
|
||||
{
|
||||
if (song == null || width < 1 || height < 1)
|
||||
if (width < 1 || height < 1)
|
||||
return null;
|
||||
|
||||
if (TEXT_SIZE == -1)
|
||||
@ -346,69 +349,76 @@ public final class CoverBitmap {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
private static Bitmap createZoomedBitmap(Context context, Song song, int width, int height, Bitmap bitmap)
|
||||
/**
|
||||
* Scales a bitmap to completely fill a rectangle of the given size. Aspect
|
||||
* ratio is preserved, thus, parts of the image will be cut off if the
|
||||
* aspect ratio of the rectangle does not match that of the source bitmap.
|
||||
*
|
||||
* @param source The source bitmap.
|
||||
* @param width Width of the result
|
||||
* @param height Height of the result
|
||||
* @param reuse A bitmap to store the result in if possible
|
||||
* @return The zoomed bitmap.
|
||||
*/
|
||||
public static Bitmap createZoomedBitmap(Bitmap source, int width, int height, Bitmap reuse)
|
||||
{
|
||||
if (song == null || width < 1 || height < 1)
|
||||
if (source == null || width < 1 || height < 1)
|
||||
return null;
|
||||
|
||||
Bitmap cover = song.getCover(context);
|
||||
if (cover == null)
|
||||
return null;
|
||||
Bitmap bitmap = null;
|
||||
|
||||
if (bitmap != null && (bitmap.getHeight() != height || bitmap.getWidth() != width)) {
|
||||
bitmap.recycle();
|
||||
bitmap = null;
|
||||
if (reuse != null) {
|
||||
if (reuse.getHeight() == height && reuse.getWidth() == width)
|
||||
bitmap = reuse;
|
||||
else
|
||||
reuse.recycle();
|
||||
}
|
||||
|
||||
if (bitmap == null)
|
||||
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
|
||||
int coverWidth = cover.getWidth();
|
||||
int coverHeight = cover.getHeight();
|
||||
int sourceWidth = source.getWidth();
|
||||
int sourceHeight = source.getHeight();
|
||||
int size = Math.max(width, height);
|
||||
float scale = coverWidth < coverHeight ? (float)size / coverWidth : (float)size / coverHeight;
|
||||
float scale = sourceWidth < sourceHeight ? (float)size / sourceWidth : (float)size / sourceHeight;
|
||||
|
||||
int srcWidth = (int)(Math.min(width, coverWidth * scale) / scale);
|
||||
int srcHeight = (int)(Math.min(height, coverHeight * scale) / scale);
|
||||
int xOffset = (coverWidth - srcWidth) / 2;
|
||||
int yOffset = (coverHeight - srcHeight) / 2;
|
||||
Rect src = new Rect(xOffset, yOffset, coverWidth - xOffset, coverHeight - yOffset);
|
||||
int srcWidth = (int)(Math.min(width, sourceWidth * scale) / scale);
|
||||
int srcHeight = (int)(Math.min(height, sourceHeight * scale) / scale);
|
||||
int xOffset = (sourceWidth - srcWidth) / 2;
|
||||
int yOffset = (sourceHeight - srcHeight) / 2;
|
||||
Rect src = new Rect(xOffset, yOffset, sourceWidth - xOffset, sourceHeight - yOffset);
|
||||
Rect dest = new Rect(0, 0, width, height);
|
||||
canvas.drawBitmap(cover, src, dest, null);
|
||||
canvas.drawBitmap(source, src, dest, null);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales a cover to fit in a rectangle of the given size. Aspect ratio is
|
||||
* Scales a bitmap to fit in a rectangle of the given size. Aspect ratio is
|
||||
* preserved. At least one dimension of the result will match the provided
|
||||
* dimension exactly.
|
||||
*
|
||||
* @param context A context to use.
|
||||
* @param song The song to display information for
|
||||
* @param source The source bitmap.
|
||||
* @param width Maximum width of image
|
||||
* @param height Maximum height of image
|
||||
* @param bitmap A bitmap that will simply be recycled.
|
||||
* @return The scaled Bitmap, or null if a cover could not be found.
|
||||
* @param reuse A bitmap that will simply be recycled. (This method does not
|
||||
* support reuse.)
|
||||
* @return The scaled bitmap.
|
||||
*/
|
||||
private static Bitmap createScaledBitmap(Context context, Song song, int width, int height, Bitmap bitmap)
|
||||
public static Bitmap createScaledBitmap(Bitmap source, int width, int height, Bitmap reuse)
|
||||
{
|
||||
if (song == null || width < 1 || height < 1)
|
||||
if (source == null || width < 1 || height < 1)
|
||||
return null;
|
||||
|
||||
if (bitmap != null)
|
||||
bitmap.recycle();
|
||||
if (reuse != null)
|
||||
reuse.recycle();
|
||||
|
||||
Bitmap cover = song.getCover(context);
|
||||
if (cover == null)
|
||||
return null;
|
||||
|
||||
int coverWidth = cover.getWidth();
|
||||
int coverHeight = cover.getHeight();
|
||||
float scale = Math.min((float)width / coverWidth, (float)height / coverHeight);
|
||||
coverWidth *= scale;
|
||||
coverHeight *= scale;
|
||||
return Bitmap.createScaledBitmap(cover, coverWidth, coverHeight, false);
|
||||
int sourceWidth = source.getWidth();
|
||||
int sourceHeight = source.getHeight();
|
||||
float scale = Math.min((float)width / sourceWidth, (float)height / sourceHeight);
|
||||
sourceWidth *= scale;
|
||||
sourceHeight *= scale;
|
||||
return Bitmap.createScaledBitmap(source, sourceWidth, sourceHeight, false);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ package org.kreed.vanilla;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.os.Handler;
|
||||
@ -75,6 +76,10 @@ public final class CoverView extends View implements Handler.Callback {
|
||||
* Cache of cover bitmaps generated for songs. The song ids are the keys.
|
||||
*/
|
||||
private final Cache<Bitmap> mBitmapCache = new Cache<Bitmap>(8);
|
||||
/**
|
||||
* Cover art to use when a song has no cover art in no info display styles.
|
||||
*/
|
||||
private Bitmap mDefaultCover;
|
||||
|
||||
private final Scroller mScroller;
|
||||
private VelocityTracker mVelocityTracker;
|
||||
@ -126,6 +131,32 @@ public final class CoverView extends View implements Handler.Callback {
|
||||
scrollTo(getWidth(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the cover to show when a song has no cover art. Only used in the
|
||||
* no info modes.
|
||||
*
|
||||
* @return The default cover, now also stored in mDefaultCover.
|
||||
*/
|
||||
private Bitmap generateDefaultCover()
|
||||
{
|
||||
int style = mCoverStyle;
|
||||
Bitmap result = null;
|
||||
|
||||
if (style == CoverBitmap.STYLE_NO_INFO || style == CoverBitmap.STYLE_NO_INFO_ZOOMED) {
|
||||
Bitmap def = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.default_cover);
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
|
||||
if (style == CoverBitmap.STYLE_NO_INFO)
|
||||
result = CoverBitmap.createScaledBitmap(def, width, height, null);
|
||||
else
|
||||
result = CoverBitmap.createZoomedBitmap(def, width, height, null);
|
||||
}
|
||||
|
||||
mDefaultCover = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recreate all the necessary cached bitmaps.
|
||||
*/
|
||||
@ -137,6 +168,7 @@ public final class CoverView extends View implements Handler.Callback {
|
||||
((Bitmap)bitmaps[i]).recycle();
|
||||
bitmaps[i] = null;
|
||||
}
|
||||
mDefaultCover = null;
|
||||
for (int i = 3; --i != -1; )
|
||||
setSong(i, mSongs[i]);
|
||||
}
|
||||
@ -317,12 +349,21 @@ public final class CoverView extends View implements Handler.Callback {
|
||||
if (song == null || song.id == -1)
|
||||
return;
|
||||
|
||||
Bitmap bitmap = CoverBitmap.createBitmap(getContext(), mCoverStyle, song, getWidth(), getHeight(), mBitmapCache.discardOldest());
|
||||
if (bitmap != null) {
|
||||
mBitmaps[i] = bitmap;
|
||||
mBitmapCache.put(song.id, bitmap);
|
||||
postInvalidate();
|
||||
Bitmap reuse = mBitmapCache.discardOldest();
|
||||
if (reuse == mDefaultCover)
|
||||
reuse = null;
|
||||
|
||||
int style = mCoverStyle;
|
||||
Bitmap bitmap = CoverBitmap.createBitmap(getContext(), style, song, getWidth(), getHeight(), reuse);
|
||||
if (bitmap == null && (style == CoverBitmap.STYLE_NO_INFO || style == CoverBitmap.STYLE_NO_INFO_ZOOMED)) {
|
||||
bitmap = mDefaultCover;
|
||||
if (bitmap == null)
|
||||
bitmap = generateDefaultCover();
|
||||
}
|
||||
|
||||
mBitmaps[i] = bitmap;
|
||||
mBitmapCache.put(song.id, bitmap);
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user