Commit e30a3048 authored by Nicolas Pomepuy's avatar Nicolas Pomepuy Committed by Geoffrey Métais

Fix cards default images

parent 95bc7328
......@@ -2,42 +2,42 @@
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48"
height="48"
id="svg4682"
version="1.1"
inkscape:version="0.92.1 r15371"
sodipodi:docname="ic_song_big.svg"
inkscape:export-filename="/home/corbax/Dev/android/Icons/Test 1/ic_play_normal.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48"
height="48"
id="svg4682"
version="1.1"
inkscape:version="0.92.4 (33fec40, 2019-01-16)"
sodipodi:docname="ic_song_big.svg"
inkscape:export-filename="/home/corbax/Dev/android/Icons/Test 1/ic_play_normal.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs4684" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.9195959"
inkscape:cx="-3.6004423"
inkscape:cy="20.263937"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="1920"
inkscape:window-height="1027"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1">
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.6"
inkscape:cx="24.12025"
inkscape:cy="26.028405"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="1049"
inkscape:window-height="599"
inkscape:window-x="1968"
inkscape:window-y="150"
inkscape:window-maximized="0">
<inkscape:grid
type="xygrid"
id="grid816" />
......@@ -60,9 +60,10 @@
id="layer1"
transform="translate(0,-1004.3622)">
<path
inkscape:connector-curvature="0"
id="path6959"
d="m 39.298845,1013.0639 c -3.60156,-3.6022 -9.44082,-3.6022 -13.04237,0 -3.60155,3.6022 -3.60155,9.4426 0,13.0447 3.60155,3.6022 9.44081,3.6022 13.04237,0 3.60154,-3.6021 3.60154,-9.4425 0,-13.0447 z m -17.93325,7.3377 -14.6726595,18.7518 c -2.69551,3.446 3.10871,9.1927 6.5211795,6.5224 l 18.7484,-14.6754 c -2.67004,-0.19 -5.29497,-1.2194 -7.33633,-3.2612 -2.04137,-2.0417 -3.07051,-4.6671 -3.26059,-7.3376 z"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#757575;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.018;marker:none;enable-background:accumulate" />
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#757575;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.9861207;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
d="m 36.937177,1010.364 c -6.459386,2.8718 -12.477648,5.5364 -18.579608,8.2571 -1.669886,0.7447 -1.669886,2.9926 -1.669886,2.9926 v 14.6598 c -0.186745,-0.022 -0.37448,-0.034 -0.562486,-0.036 -2.79587,0 -5.062373,2.2665 -5.062373,5.0623 0,2.796 2.266503,5.0624 5.062373,5.0624 2.795871,0 5.062374,-2.2664 5.062374,-5.0624 v -17.437 l 11.249719,-4.4999 v 12.9723 c -0.186746,-0.023 -0.374481,-0.034 -0.562487,-0.036 -2.795869,0 -5.062374,2.2665 -5.062374,5.0623 0,2.796 2.266504,5.0624 5.062374,5.0624 2.79587,0 5.062373,-2.2664 5.062373,-5.0624 v -26.9993 z"
id="path7165"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cscccsssccccssscc"/>
</g>
</svg>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="90dp"
android:height="90dp"
android:viewportWidth="48"
android:viewportHeight="48">
<path
android:pathData="m36.9372,6.0018c-6.4594,2.8718 -12.4776,5.5364 -18.5796,8.2571 -1.6699,0.7447 -1.6699,2.9926 -1.6699,2.9926v14.6598c-0.1867,-0.022 -0.3745,-0.034 -0.5625,-0.036 -2.7959,0 -5.0624,2.2665 -5.0624,5.0623 0,2.796 2.2665,5.0624 5.0624,5.0624 2.7959,0 5.0624,-2.2664 5.0624,-5.0624v-17.437l11.2497,-4.4999v12.9723c-0.1867,-0.023 -0.3745,-0.034 -0.5625,-0.036 -2.7959,0 -5.0624,2.2665 -5.0624,5.0623 0,2.796 2.2665,5.0624 5.0624,5.0624 2.7959,0 5.0624,-2.2664 5.0624,-5.0624v-26.9993z"
android:strokeAlpha="1"
android:strokeLineJoin="round"
android:strokeWidth="3.9861207"
android:fillColor="#757575"
android:strokeColor="#00000000"
android:fillType="nonZero"
android:fillAlpha="1"
android:strokeLineCap="round"/>
</vector>
......@@ -36,6 +36,10 @@
<variable
name="holder"
type="org.videolan.vlc.gui.audio.AudioBrowserAdapter.MediaItemCardViewHolder" />
<variable
name="scaleType"
type="android.widget.ImageView.ScaleType"/>
</data>
<androidx.cardview.widget.CardView
......@@ -63,7 +67,8 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_gravity="center"
android:background="@{cover}"
android:src="@{cover}"
android:scaleType="@{scaleType}"
android:visibility="@{(item.getItemType() &amp; (MediaLibraryItem.TYPE_ALBUM|MediaLibraryItem.TYPE_ARTIST|MediaLibraryItem.TYPE_MEDIA|MediaLibraryItem.TYPE_PLAYLIST)) != 0 ? View.VISIBLE : View.GONE, default=gone}"
tools:srcCompat="@tools:sample/avatars"
vlc:imageWidth="@{imageWidth}"
......
......@@ -41,11 +41,13 @@
name="cover"
type="android.graphics.drawable.BitmapDrawable" />
<variable
name="isSquare"
type="Boolean" />
<variable
name="scaleType"
type="android.widget.ImageView.ScaleType"/>
<variable
name="holder"
......@@ -81,6 +83,7 @@
tools:srcCompat="@drawable/ic_album_big"
vlc:constraintRatio="@{isSquare}"
android:src="@{cover}"
android:scaleType="@{scaleType}"
vlc:layout_constraintEnd_toEndOf="parent"
vlc:layout_constraintStart_toStartOf="parent"
vlc:layout_constraintTop_toTopOf="parent"
......
......@@ -31,6 +31,7 @@ import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.core.view.MotionEventCompat
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
......@@ -78,7 +79,7 @@ class AudioBrowserAdapter @JvmOverloads constructor(private val type: Int, priva
if (mIEventsHandler is Context)
ctx = mIEventsHandler
else if (mIEventsHandler is Fragment) ctx = (mIEventsHandler as Fragment).context
mDefaultCover = if (ctx != null) getAudioIconDrawable(ctx, type) else null
mDefaultCover = if (ctx != null) getAudioIconDrawable(ctx, type, displayInCard()) else null
}
constructor(typeMedia: Int, eventsHandler: IEventsHandler, itemSize: Int) : this(typeMedia, eventsHandler) {
......@@ -87,7 +88,7 @@ class AudioBrowserAdapter @JvmOverloads constructor(private val type: Int, priva
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AbstractMediaItemViewHolder<ViewDataBinding> {
val inflater = parent.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
return if (type == MediaLibraryItem.TYPE_PLAYLIST || type == MediaLibraryItem.TYPE_ARTIST || type == MediaLibraryItem.TYPE_ALBUM) {
return if (displayInCard()) {
val binding = AudioBrowserCardItemBinding.inflate(inflater, parent, false)
MediaItemCardViewHolder(binding) as AbstractMediaItemViewHolder<ViewDataBinding>
} else {
......@@ -96,6 +97,9 @@ class AudioBrowserAdapter @JvmOverloads constructor(private val type: Int, priva
}
}
private fun displayInCard() =
type == MediaLibraryItem.TYPE_PLAYLIST || type == MediaLibraryItem.TYPE_ARTIST || type == MediaLibraryItem.TYPE_ALBUM
override fun onBindViewHolder(holder: AbstractMediaItemViewHolder<ViewDataBinding>, position: Int) {
if (position >= itemCount) return
val item = getItem(position)
......@@ -247,6 +251,7 @@ class AudioBrowserAdapter @JvmOverloads constructor(private val type: Int, priva
init {
binding.holder = this
binding.scaleType = ImageView.ScaleType.CENTER_INSIDE
if (mDefaultCover != null) binding.cover = mDefaultCover
if (AndroidUtil.isMarshMallowOrLater)
itemView.setOnContextClickListener { v ->
......
package org.videolan.vlc.gui.helpers
import android.annotation.TargetApi
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.VectorDrawable
import android.net.Uri
import android.os.Build
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.annotation.MainThread
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.databinding.BindingAdapter
......@@ -17,6 +23,7 @@ import androidx.databinding.DataBindingUtil
import androidx.databinding.OnRebindCallback
import androidx.databinding.ViewDataBinding
import androidx.leanback.widget.ImageCardView
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
import kotlinx.coroutines.*
import org.videolan.medialibrary.interfaces.AbstractMedialibrary
import org.videolan.medialibrary.interfaces.media.AbstractMediaWrapper
......@@ -24,6 +31,7 @@ import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.vlc.BR
import org.videolan.vlc.R
import org.videolan.vlc.VLCApplication
import org.videolan.vlc.databinding.AudioBrowserCardItemBinding
import org.videolan.vlc.databinding.MediaBrowserTvItemBinding
import org.videolan.vlc.gui.tv.TvUtil
import org.videolan.vlc.util.AppScope
......@@ -80,15 +88,33 @@ fun loadPlaylistImageWithWidth(v: ImageView, item: MediaLibraryItem?, imageWidth
AppScope.launch { getPlaylistImage(v, item, binding, imageWidth) }
}
fun getAudioIconDrawable(context: Context?, type: Int): BitmapDrawable? = context?.let {
fun getAudioIconDrawable(context: Context?, type: Int, big: Boolean = false): BitmapDrawable? = context?.let {
when (type) {
MediaLibraryItem.TYPE_ALBUM -> UiTools.getDefaultAlbumDrawable(it)
MediaLibraryItem.TYPE_ARTIST -> UiTools.getDefaultArtistDrawable(it)
MediaLibraryItem.TYPE_MEDIA -> UiTools.getDefaultAudioDrawable(it)
MediaLibraryItem.TYPE_ALBUM -> if (big) UiTools.getDefaultAlbumDrawableBig(it) else UiTools.getDefaultAlbumDrawable(it)
MediaLibraryItem.TYPE_ARTIST -> if (big) UiTools.getDefaultArtistDrawableBig(it) else UiTools.getDefaultArtistDrawable(it)
MediaLibraryItem.TYPE_MEDIA -> if (big) UiTools.getDefaultAudioDrawableBig(it) else UiTools.getDefaultAudioDrawable(it)
else -> null
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
fun getBitmapFromDrawable(context: Context, @DrawableRes drawableId: Int): Bitmap {
val drawable = AppCompatResources.getDrawable(context, drawableId)
return if (drawable is BitmapDrawable) {
drawable.bitmap
} else if (drawable is VectorDrawableCompat || drawable is VectorDrawable) {
val bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height)
drawable.draw(canvas)
bitmap
} else {
throw IllegalArgumentException("unsupported drawable type")
}
}
fun getMediaIconDrawable(context: Context, type: Int): BitmapDrawable? = when (type) {
AbstractMediaWrapper.TYPE_VIDEO -> UiTools.getDefaultVideoDrawable(context)
else -> UiTools.getDefaultAudioDrawable(context)
......@@ -175,10 +201,20 @@ private suspend fun getImage(v: View, item: MediaLibraryItem, binding: ViewDataB
binding?.removeOnRebindCallback(rebindCallbacks!!)
return
}
if (image == null) {
//keep the default image
binding?.setVariable(BR.scaleType, ImageView.ScaleType.CENTER_INSIDE)
binding?.removeOnRebindCallback(rebindCallbacks!!)
return
}
if (!bindChanged) updateImageView(image, v, binding)
binding?.removeOnRebindCallback(rebindCallbacks!!)
}
private fun isCard(binding: ViewDataBinding?) = binding is AudioBrowserCardItemBinding
private suspend fun getPlaylistImage(v: View, item: MediaLibraryItem, binding: ViewDataBinding?, width: Int) {
var bindChanged = false
val rebindCallbacks = if (binding !== null) object : OnRebindCallback<ViewDataBinding>() {
......@@ -203,7 +239,7 @@ private suspend fun getPlaylistImage(v: View, item: MediaLibraryItem, binding: V
fun updateImageView(bitmap: Bitmap?, target: View, vdb: ViewDataBinding?) {
if (bitmap === null || bitmap.width <= 1 || bitmap.height <= 1) return
if (vdb !== null && !isForTV(vdb)) {
vdb.setVariable(BR.scaleType, ImageView.ScaleType.FIT_CENTER)
vdb.setVariable(BR.scaleType, if (isCard(vdb)) ImageView.ScaleType.CENTER_CROP else ImageView.ScaleType.FIT_CENTER)
vdb.setVariable(BR.cover, BitmapDrawable(target.resources, bitmap))
vdb.setVariable(BR.protocol, null)
} else when (target) {
......
......@@ -94,6 +94,11 @@ object UiTools {
private var DEFAULT_COVER_ALBUM_DRAWABLE: BitmapDrawable? = null
private var DEFAULT_COVER_ARTIST_DRAWABLE: BitmapDrawable? = null
private var DEFAULT_COVER_VIDEO_DRAWABLE_BIG: BitmapDrawable? = null
private var DEFAULT_COVER_AUDIO_DRAWABLE_BIG: BitmapDrawable? = null
private var DEFAULT_COVER_ALBUM_DRAWABLE_BIG: BitmapDrawable? = null
private var DEFAULT_COVER_ARTIST_DRAWABLE_BIG: BitmapDrawable? = null
private val sHandler = Handler(Looper.getMainLooper())
const val DELETE_DURATION = 3000
......@@ -127,6 +132,36 @@ object UiTools {
return DEFAULT_COVER_ARTIST_DRAWABLE!!
}
fun getDefaultVideoDrawableBig(context: Context): BitmapDrawable {
if (DEFAULT_COVER_VIDEO_DRAWABLE_BIG == null) {
val DEFAULT_COVER_VIDEO = BitmapCache.getFromResource(context.resources, R.drawable.ic_no_thumbnail_1610)
DEFAULT_COVER_VIDEO_DRAWABLE_BIG = BitmapDrawable(context.resources, DEFAULT_COVER_VIDEO)
}
return DEFAULT_COVER_VIDEO_DRAWABLE_BIG!!
}
fun getDefaultAudioDrawableBig(context: Context): BitmapDrawable {
if (DEFAULT_COVER_AUDIO_DRAWABLE_BIG == null) {
val DEFAULT_COVER_AUDIO = BitmapCache.getFromResource(context.resources, R.drawable.ic_no_song)
DEFAULT_COVER_AUDIO_DRAWABLE_BIG = BitmapDrawable(context.resources, DEFAULT_COVER_AUDIO)
}
return DEFAULT_COVER_AUDIO_DRAWABLE_BIG!!
}
fun getDefaultAlbumDrawableBig(context: Context): BitmapDrawable {
if (DEFAULT_COVER_ALBUM_DRAWABLE_BIG == null) {
DEFAULT_COVER_ALBUM_DRAWABLE_BIG = BitmapDrawable(context.resources, BitmapCache.getFromResource(context.resources, R.drawable.ic_album_big))
}
return DEFAULT_COVER_ALBUM_DRAWABLE_BIG!!
}
fun getDefaultArtistDrawableBig(context: Context): BitmapDrawable {
if (DEFAULT_COVER_ARTIST_DRAWABLE_BIG == null) {
DEFAULT_COVER_ARTIST_DRAWABLE_BIG = BitmapDrawable(context.resources, BitmapCache.getFromResource(context.resources, R.drawable.ic_artist_big))
}
return DEFAULT_COVER_ARTIST_DRAWABLE_BIG!!
}
/**
* Print an on-screen message to alert the user
*/
......@@ -219,8 +254,8 @@ object UiTools {
link.text = Html.fromHtml(v.context.getString(R.string.about_link))
val feedback : TextView= v.findViewById(R.id.feedback)
feedback.text = Html.fromHtml(v.getContext().getString(R.string.feedback_link, v.getContext().getString(R.string.feedback_forum)));
feedback.movementMethod = LinkMovementMethod.getInstance();
feedback.text = Html.fromHtml(v.context.getString(R.string.feedback_link, v.context.getString(R.string.feedback_forum)))
feedback.movementMethod = LinkMovementMethod.getInstance()
val revision = v.context.getString(R.string.build_revision) + " VLC: " + v.context.getString(R.string.build_vlc_revision)
val builddate = v.context.getString(R.string.build_time)
......
......@@ -46,6 +46,7 @@ import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.vlc.R
import org.videolan.vlc.VLCApplication
import org.videolan.vlc.gui.helpers.AudioUtil
import org.videolan.vlc.gui.helpers.getBitmapFromDrawable
import org.videolan.vlc.gui.helpers.loadImage
import org.videolan.vlc.gui.helpers.loadPlaylistImageWithWidth
import org.videolan.vlc.util.*
......@@ -110,7 +111,7 @@ class CardPresenter(private val context: Activity) : Presenter() {
BitmapFactory.decodeResource(res, R.drawable.ic_menu_network_big)
} else
AudioUtil.readCoverBitmap(Uri.decode(mediaLibraryItem.artworkMrl), res.getDimensionPixelSize(R.dimen.tv_grid_card_thumb_width))
if (picture == null) picture = BitmapFactory.decodeResource(res, TvUtil.getIconRes(mediaLibraryItem))
if (picture == null) picture = getBitmapFromDrawable(context, TvUtil.getIconRes(mediaLibraryItem))
return picture
}
......
......@@ -7,6 +7,7 @@ import android.os.Build
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.paging.PagedList
......@@ -40,7 +41,7 @@ class MediaTvItemAdapter(type: Int, private val eventsHandler: IEventsHandler, v
is Fragment -> (eventsHandler as Fragment).context
else -> null
}
defaultCover = ctx?.let { getAudioIconDrawable(it, type) }
defaultCover = ctx?.let { getAudioIconDrawable(it, type, true) }
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AbstractMediaItemViewHolder<ViewDataBinding> {
......@@ -153,6 +154,7 @@ class MediaTvItemAdapter(type: Int, private val eventsHandler: IEventsHandler, v
init {
binding.holder = this
binding.scaleType = ImageView.ScaleType.CENTER_INSIDE
if (defaultCover != null) binding.cover = defaultCover
if (AndroidUtil.isMarshMallowOrLater)
itemView.setOnContextClickListener { v ->
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment