mirror of
https://gitlab.com/ultrasonic/ultrasonic.git
synced 2025-04-16 09:20:37 +03:00
Merge branch 'refactor_widget' into 'develop'
Updated widget handling and layouts, add Day&Night theme See merge request ultrasonic/ultrasonic!820
This commit is contained in:
commit
fd096212ee
@ -77,6 +77,8 @@ android {
|
||||
ignore 'MissingTranslation', 'UnusedQuantity', 'MissingQuantity'
|
||||
warning 'ImpliedQuantity'
|
||||
disable 'ObsoleteLintCustomCheck'
|
||||
textReport true
|
||||
checkDependencies true
|
||||
}
|
||||
namespace 'org.moire.ultrasonic'
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<issues format="6" by="lint 7.3.0" type="baseline" client="gradle" dependencies="false" name="AGP (7.3.0)" variant="all" version="7.3.0">
|
||||
<issues format="6" by="lint 7.3.0" type="baseline" client="gradle" dependencies="true" name="AGP (7.3.0)" variant="all" version="7.3.0">
|
||||
|
||||
<issue
|
||||
id="PluralsCandidate"
|
||||
@ -44,7 +44,7 @@
|
||||
errorLine2=" ~~~~~~~~">
|
||||
<location
|
||||
file="src/main/AndroidManifest.xml"
|
||||
line="164"
|
||||
line="128"
|
||||
column="10"/>
|
||||
</issue>
|
||||
|
||||
@ -55,7 +55,7 @@
|
||||
errorLine2=" ~~~~~~~~">
|
||||
<location
|
||||
file="src/main/AndroidManifest.xml"
|
||||
line="169"
|
||||
line="133"
|
||||
column="10"/>
|
||||
</issue>
|
||||
|
||||
@ -103,50 +103,6 @@
|
||||
column="9"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="Overdraw"
|
||||
message="Possible overdraw: Root element paints background `@drawable/appwidget_dark_bg_trans` with a theme that also paints a background (inferred theme is `@style/Theme.Material3.DynamicColors.Dark`)"
|
||||
errorLine1=" a:background="@drawable/appwidget_dark_bg_trans""
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x1.xml"
|
||||
line="7"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="Overdraw"
|
||||
message="Possible overdraw: Root element paints background `@drawable/appwidget_dark_bg_trans` with a theme that also paints a background (inferred theme is `@style/Theme.Material3.DynamicColors.Dark`)"
|
||||
errorLine1=" a:background="@drawable/appwidget_dark_bg_trans""
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x2.xml"
|
||||
line="7"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="Overdraw"
|
||||
message="Possible overdraw: Root element paints background `@drawable/appwidget_dark_bg_trans` with a theme that also paints a background (inferred theme is `@style/Theme.Material3.DynamicColors.Dark`)"
|
||||
errorLine1=" a:background="@drawable/appwidget_dark_bg_trans""
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x3.xml"
|
||||
line="7"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="Overdraw"
|
||||
message="Possible overdraw: Root element paints background `@drawable/appwidget_dark_bg_trans` with a theme that also paints a background (inferred theme is `@style/Theme.Material3.DynamicColors.Dark`)"
|
||||
errorLine1=" a:background="@drawable/appwidget_dark_bg_trans" >"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x4.xml"
|
||||
line="8"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="UnusedResources"
|
||||
message="The resource `R.drawable.ic_baseline_close` appears to be unused"
|
||||
@ -378,182 +334,6 @@
|
||||
column="4"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
errorLine1=" <ImageView"
|
||||
errorLine2=" ~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x1.xml"
|
||||
line="10"
|
||||
column="6"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
errorLine1=" <ImageButton"
|
||||
errorLine2=" ~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x1.xml"
|
||||
line="76"
|
||||
column="14"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
errorLine1=" <ImageButton"
|
||||
errorLine2=" ~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x1.xml"
|
||||
line="85"
|
||||
column="14"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
errorLine1=" <ImageButton"
|
||||
errorLine2=" ~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x1.xml"
|
||||
line="94"
|
||||
column="14"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
errorLine1=" <ImageView"
|
||||
errorLine2=" ~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x2.xml"
|
||||
line="10"
|
||||
column="6"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
errorLine1=" <ImageButton"
|
||||
errorLine2=" ~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x2.xml"
|
||||
line="97"
|
||||
column="14"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
errorLine1=" <ImageButton"
|
||||
errorLine2=" ~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x2.xml"
|
||||
line="106"
|
||||
column="14"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
errorLine1=" <ImageButton"
|
||||
errorLine2=" ~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x2.xml"
|
||||
line="115"
|
||||
column="14"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
errorLine1=" <ImageView"
|
||||
errorLine2=" ~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x3.xml"
|
||||
line="10"
|
||||
column="6"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
errorLine1=" <ImageButton"
|
||||
errorLine2=" ~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x3.xml"
|
||||
line="99"
|
||||
column="14"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
errorLine1=" <ImageButton"
|
||||
errorLine2=" ~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x3.xml"
|
||||
line="108"
|
||||
column="14"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
errorLine1=" <ImageButton"
|
||||
errorLine2=" ~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x3.xml"
|
||||
line="117"
|
||||
column="14"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
errorLine1=" <ImageView"
|
||||
errorLine2=" ~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x4.xml"
|
||||
line="10"
|
||||
column="6"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
errorLine1=" <ImageButton"
|
||||
errorLine2=" ~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x4.xml"
|
||||
line="100"
|
||||
column="14"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
errorLine1=" <ImageButton"
|
||||
errorLine2=" ~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x4.xml"
|
||||
line="109"
|
||||
column="14"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
errorLine1=" <ImageButton"
|
||||
errorLine2=" ~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x4.xml"
|
||||
line="118"
|
||||
column="14"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
@ -609,127 +389,6 @@
|
||||
column="10"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardcodedText"
|
||||
message="Hardcoded string "Title", should use `@string` resource"
|
||||
errorLine1=" a:text="Title""
|
||||
errorLine2=" ~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x1.xml"
|
||||
line="46"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardcodedText"
|
||||
message="Hardcoded string "Artist", should use `@string` resource"
|
||||
errorLine1=" a:text="Artist""
|
||||
errorLine2=" ~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x1.xml"
|
||||
line="64"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardcodedText"
|
||||
message="Hardcoded string "Title", should use `@string` resource"
|
||||
errorLine1=" a:text="Title""
|
||||
errorLine2=" ~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x2.xml"
|
||||
line="48"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardcodedText"
|
||||
message="Hardcoded string "Artist", should use `@string` resource"
|
||||
errorLine1=" a:text="Artist""
|
||||
errorLine2=" ~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x2.xml"
|
||||
line="65"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardcodedText"
|
||||
message="Hardcoded string "Album", should use `@string` resource"
|
||||
errorLine1=" a:text="Album""
|
||||
errorLine2=" ~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x2.xml"
|
||||
line="82"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardcodedText"
|
||||
message="Hardcoded string "Title", should use `@string` resource"
|
||||
errorLine1=" a:text="Title""
|
||||
errorLine2=" ~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x3.xml"
|
||||
line="50"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardcodedText"
|
||||
message="Hardcoded string "Artist", should use `@string` resource"
|
||||
errorLine1=" a:text="Artist""
|
||||
errorLine2=" ~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x3.xml"
|
||||
line="66"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardcodedText"
|
||||
message="Hardcoded string "Album", should use `@string` resource"
|
||||
errorLine1=" a:text="Album""
|
||||
errorLine2=" ~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x3.xml"
|
||||
line="83"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardcodedText"
|
||||
message="Hardcoded string "Title", should use `@string` resource"
|
||||
errorLine1=" a:text="Title""
|
||||
errorLine2=" ~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x4.xml"
|
||||
line="51"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardcodedText"
|
||||
message="Hardcoded string "Artist", should use `@string` resource"
|
||||
errorLine1=" a:text="Artist""
|
||||
errorLine2=" ~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x4.xml"
|
||||
line="67"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardcodedText"
|
||||
message="Hardcoded string "Album", should use `@string` resource"
|
||||
errorLine1=" a:text="Album""
|
||||
errorLine2=" ~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/res/layout/appwidget4x4.xml"
|
||||
line="84"
|
||||
column="16"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardcodedText"
|
||||
message="Hardcoded string "0 dB", should use `@string` resource"
|
||||
|
@ -108,8 +108,8 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver
|
||||
android:name=".provider.UltrasonicAppWidgetProvider4X1"
|
||||
android:label="Ultrasonic (4x1)"
|
||||
android:name=".provider.UltrasonicAppWidgetProvider"
|
||||
android:label="Ultrasonic"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
|
||||
@ -117,43 +117,7 @@
|
||||
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/appwidget_info_4x1"/>
|
||||
</receiver>
|
||||
<receiver
|
||||
android:name=".provider.UltrasonicAppWidgetProvider4X2"
|
||||
android:label="Ultrasonic (4x2)"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/appwidget_info_4x2"/>
|
||||
</receiver>
|
||||
<receiver
|
||||
android:name=".provider.UltrasonicAppWidgetProvider4X3"
|
||||
android:label="Ultrasonic (4x3)"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/appwidget_info_4x3"/>
|
||||
</receiver>
|
||||
<receiver
|
||||
android:name=".provider.UltrasonicAppWidgetProvider4X4"
|
||||
android:label="Ultrasonic (4x4)"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/appwidget_info_4x4"/>
|
||||
android:resource="@xml/appwidget_info"/>
|
||||
</receiver>
|
||||
<receiver android:name=".receiver.MediaButtonIntentReceiver"
|
||||
android:exported="true">
|
||||
|
@ -13,6 +13,7 @@ import android.content.Intent
|
||||
import android.content.res.ColorStateList
|
||||
import android.content.res.Resources
|
||||
import android.media.AudioManager
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.provider.MediaStore
|
||||
import android.provider.SearchRecentSuggestions
|
||||
@ -246,14 +247,19 @@ class NavigationActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
private fun updateNavigationHeaderForServer() {
|
||||
// Only show the vector graphic on Android 11 or earlier
|
||||
val showVectorBackground = (Build.VERSION.SDK_INT < Build.VERSION_CODES.S)
|
||||
|
||||
val activeServer = activeServerProvider.getActiveServer()
|
||||
|
||||
if (cachedServerCount == 0)
|
||||
selectServerButton?.text = getString(R.string.main_setup_server, activeServer.name)
|
||||
else selectServerButton?.text = activeServer.name
|
||||
|
||||
val foregroundColor = ServerColor.getForegroundColor(this, activeServer.color)
|
||||
val backgroundColor = ServerColor.getBackgroundColor(this, activeServer.color)
|
||||
val foregroundColor =
|
||||
ServerColor.getForegroundColor(this, activeServer.color, showVectorBackground)
|
||||
val backgroundColor =
|
||||
ServerColor.getBackgroundColor(this, activeServer.color)
|
||||
|
||||
if (activeServer.index == 0)
|
||||
selectServerButton?.icon =
|
||||
@ -265,6 +271,11 @@ class NavigationActivity : AppCompatActivity() {
|
||||
selectServerButton?.iconTint = ColorStateList.valueOf(foregroundColor)
|
||||
selectServerButton?.setTextColor(foregroundColor)
|
||||
headerBackgroundImage?.setBackgroundColor(backgroundColor)
|
||||
|
||||
// Hide the vector graphic on Android 12 or later
|
||||
if (!showVectorBackground) {
|
||||
headerBackgroundImage?.setImageDrawable(null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package org.moire.ultrasonic.adapters
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.MotionEvent
|
||||
@ -21,7 +20,6 @@ class TrackViewBinder(
|
||||
val onContextMenuClick: ((MenuItem, Track) -> Boolean)? = null,
|
||||
val checkable: Boolean,
|
||||
val draggable: Boolean,
|
||||
context: Context,
|
||||
val lifecycleOwner: LifecycleOwner,
|
||||
val createContextMenu: (View, Track) -> PopupMenu = { view, _ ->
|
||||
Utils.createPopupMenu(
|
||||
@ -36,8 +34,6 @@ class TrackViewBinder(
|
||||
// Set our layout files
|
||||
val layout = R.layout.list_item_track
|
||||
|
||||
private val imageHelper: Utils.ImageHelper = Utils.ImageHelper(context)
|
||||
|
||||
override fun onCreateViewHolder(inflater: LayoutInflater, parent: ViewGroup): TrackViewHolder {
|
||||
return TrackViewHolder(inflater.inflate(layout, parent, false))
|
||||
}
|
||||
@ -56,8 +52,6 @@ class TrackViewBinder(
|
||||
}
|
||||
}
|
||||
|
||||
holder.imageHelper = imageHelper
|
||||
|
||||
// Remove observer before binding
|
||||
holder.observableChecked.removeObservers(lifecycleOwner)
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
package org.moire.ultrasonic.adapters
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.View
|
||||
import android.widget.Checkable
|
||||
import android.widget.CheckedTextView
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@ -38,7 +38,6 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
|
||||
var check: CheckedTextView = view.findViewById(R.id.song_check)
|
||||
var drag: ImageView = view.findViewById(R.id.song_drag)
|
||||
var observableChecked = MutableLiveData(false)
|
||||
lateinit var imageHelper: Utils.ImageHelper
|
||||
|
||||
private var rating: LinearLayout = view.findViewById(R.id.song_five_star)
|
||||
private var fiveStar1: ImageView = view.findViewById(R.id.song_five_star_1)
|
||||
@ -125,11 +124,15 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
|
||||
rxBusSubscription?.dispose()
|
||||
}
|
||||
|
||||
private val playingIcon by lazy {
|
||||
ContextCompat.getDrawable(view.context, R.drawable.ic_stat_play)!!
|
||||
}
|
||||
|
||||
private fun setPlayIcon(isPlaying: Boolean) {
|
||||
if (isPlaying && !isPlayingCached) {
|
||||
isPlayingCached = true
|
||||
title.setCompoundDrawablesWithIntrinsicBounds(
|
||||
imageHelper.playingImage, null, null, null
|
||||
playingIcon, null, null, null
|
||||
)
|
||||
} else if (!isPlaying && isPlayingCached) {
|
||||
isPlayingCached = false
|
||||
@ -214,13 +217,13 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
|
||||
|
||||
when (status) {
|
||||
DownloadState.DONE -> {
|
||||
showStatusImage(imageHelper.downloadedImage)
|
||||
showStatusImage(R.drawable.ic_downloaded)
|
||||
}
|
||||
DownloadState.PINNED -> {
|
||||
showStatusImage(imageHelper.pinImage)
|
||||
showStatusImage(R.drawable.ic_menu_pin)
|
||||
}
|
||||
DownloadState.FAILED -> {
|
||||
showStatusImage(imageHelper.errorImage)
|
||||
showStatusImage(R.drawable.ic_baseline_error)
|
||||
}
|
||||
DownloadState.DOWNLOADING -> {
|
||||
showProgress()
|
||||
@ -237,10 +240,14 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
|
||||
}
|
||||
}
|
||||
|
||||
private fun showStatusImage(image: Drawable?) {
|
||||
private fun showStatusImage(image: Int?) {
|
||||
progressIndicator.isVisible = false
|
||||
statusImage.isVisible = true
|
||||
statusImage.setImageDrawable(image)
|
||||
if (image != null) {
|
||||
statusImage.setImageResource(image)
|
||||
} else {
|
||||
statusImage.setImageDrawable(null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showIndefiniteProgress() {
|
||||
|
@ -1,15 +1,11 @@
|
||||
package org.moire.ultrasonic.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.MenuInflater
|
||||
import android.view.View
|
||||
import android.widget.PopupMenu
|
||||
import androidx.core.content.ContextCompat
|
||||
import org.moire.ultrasonic.R
|
||||
import org.moire.ultrasonic.data.ActiveServerProvider
|
||||
import org.moire.ultrasonic.domain.Identifiable
|
||||
import org.moire.ultrasonic.util.Settings
|
||||
|
||||
object Utils {
|
||||
@JvmStatic
|
||||
@ -31,41 +27,6 @@ object Utils {
|
||||
return popup
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides cached drawables for the UI
|
||||
*/
|
||||
class ImageHelper(context: Context) {
|
||||
|
||||
lateinit var errorImage: Drawable
|
||||
lateinit var pinImage: Drawable
|
||||
lateinit var downloadedImage: Drawable
|
||||
lateinit var downloadingImage: List<Drawable>
|
||||
lateinit var playingImage: Drawable
|
||||
var theme: String
|
||||
|
||||
init {
|
||||
theme = Settings.theme
|
||||
getDrawables(context)
|
||||
}
|
||||
|
||||
private fun getDrawables(context: Context) {
|
||||
pinImage = ContextCompat.getDrawable(context, R.drawable.ic_menu_pin)!!
|
||||
downloadedImage =
|
||||
ContextCompat.getDrawable(context, R.drawable.stat_sys_download_anim_0)!!
|
||||
errorImage = ContextCompat.getDrawable(context, R.drawable.ic_baseline_error)!!
|
||||
downloadingImage = listOf(
|
||||
ContextCompat.getDrawable(context, R.drawable.stat_sys_download_anim_1)!!,
|
||||
ContextCompat.getDrawable(context, R.drawable.stat_sys_download_anim_2)!!,
|
||||
ContextCompat.getDrawable(context, R.drawable.stat_sys_download_anim_3)!!,
|
||||
ContextCompat.getDrawable(context, R.drawable.stat_sys_download_anim_4)!!,
|
||||
ContextCompat.getDrawable(context, R.drawable.stat_sys_download_anim_5)!!,
|
||||
ContextCompat.getDrawable(context, R.drawable.stat_sys_download_anim_6)!!,
|
||||
ContextCompat.getDrawable(context, R.drawable.stat_sys_download_anim_7)!!,
|
||||
)
|
||||
playingImage = ContextCompat.getDrawable(context, R.drawable.ic_stat_play)!!
|
||||
}
|
||||
}
|
||||
|
||||
interface SectionedBinder {
|
||||
fun getSectionName(item: Identifiable): String
|
||||
}
|
||||
|
@ -57,7 +57,6 @@ class DownloadsFragment : MultiListFragment<Track>() {
|
||||
{ _, _ -> true },
|
||||
checkable = false,
|
||||
draggable = false,
|
||||
context = requireContext(),
|
||||
lifecycleOwner = viewLifecycleOwner
|
||||
)
|
||||
)
|
||||
|
@ -69,7 +69,7 @@ class EditServerFragment : Fragment(), OnBackPressedHandler {
|
||||
private var userNameEditText: TextInputLayout? = null
|
||||
private var passwordEditText: TextInputLayout? = null
|
||||
private var selfSignedSwitch: SwitchMaterial? = null
|
||||
private var ldapSwitch: SwitchMaterial? = null
|
||||
private var plaintextSwitch: SwitchMaterial? = null
|
||||
private var jukeboxSwitch: SwitchMaterial? = null
|
||||
private var saveButton: Button? = null
|
||||
private var testButton: Button? = null
|
||||
@ -102,7 +102,7 @@ class EditServerFragment : Fragment(), OnBackPressedHandler {
|
||||
userNameEditText = view.findViewById(R.id.edit_server_username)
|
||||
passwordEditText = view.findViewById(R.id.edit_server_password)
|
||||
selfSignedSwitch = view.findViewById(R.id.edit_self_signed)
|
||||
ldapSwitch = view.findViewById(R.id.edit_ldap)
|
||||
plaintextSwitch = view.findViewById(R.id.edit_plaintext)
|
||||
jukeboxSwitch = view.findViewById(R.id.edit_jukebox)
|
||||
saveButton = view.findViewById(R.id.edit_save)
|
||||
testButton = view.findViewById(R.id.edit_test)
|
||||
@ -195,7 +195,7 @@ class EditServerFragment : Fragment(), OnBackPressedHandler {
|
||||
|
||||
private fun updateColor(color: Int?) {
|
||||
val image = ContextCompat.getDrawable(requireContext(), R.drawable.thumb_drawable)
|
||||
currentColor = ServerColor.getBackgroundColor(requireContext(), color)
|
||||
currentColor = color ?: ServerColor.getBackgroundColor(requireContext(), null)
|
||||
image?.setTint(currentColor)
|
||||
serverColorImageView?.background = image
|
||||
}
|
||||
@ -221,7 +221,7 @@ class EditServerFragment : Fragment(), OnBackPressedHandler {
|
||||
::selfSignedSwitch.name, selfSignedSwitch!!.isChecked
|
||||
)
|
||||
savedInstanceState.putBoolean(
|
||||
::ldapSwitch.name, ldapSwitch!!.isChecked
|
||||
::plaintextSwitch.name, plaintextSwitch!!.isChecked
|
||||
)
|
||||
savedInstanceState.putBoolean(
|
||||
::jukeboxSwitch.name, jukeboxSwitch!!.isChecked
|
||||
@ -258,7 +258,7 @@ class EditServerFragment : Fragment(), OnBackPressedHandler {
|
||||
savedInstanceState.getString(::passwordEditText.name)
|
||||
)
|
||||
selfSignedSwitch!!.isChecked = savedInstanceState.getBoolean(::selfSignedSwitch.name)
|
||||
ldapSwitch!!.isChecked = savedInstanceState.getBoolean(::ldapSwitch.name)
|
||||
plaintextSwitch!!.isChecked = savedInstanceState.getBoolean(::plaintextSwitch.name)
|
||||
jukeboxSwitch!!.isChecked = savedInstanceState.getBoolean(::jukeboxSwitch.name)
|
||||
updateColor(savedInstanceState.getInt(::serverColorImageView.name))
|
||||
if (savedInstanceState.containsKey(::selectedColor.name))
|
||||
@ -277,7 +277,7 @@ class EditServerFragment : Fragment(), OnBackPressedHandler {
|
||||
userNameEditText!!.editText?.setText(currentServerSetting!!.userName)
|
||||
passwordEditText!!.editText?.setText(currentServerSetting!!.password)
|
||||
selfSignedSwitch!!.isChecked = currentServerSetting!!.allowSelfSignedCertificate
|
||||
ldapSwitch!!.isChecked = currentServerSetting!!.forcePlainTextPassword
|
||||
plaintextSwitch!!.isChecked = currentServerSetting!!.forcePlainTextPassword
|
||||
jukeboxSwitch!!.isChecked = currentServerSetting!!.jukeboxByDefault
|
||||
updateColor(currentServerSetting!!.color)
|
||||
}
|
||||
@ -331,7 +331,7 @@ class EditServerFragment : Fragment(), OnBackPressedHandler {
|
||||
currentServerSetting!!.userName = userNameEditText!!.editText?.text.toString()
|
||||
currentServerSetting!!.password = passwordEditText!!.editText?.text.toString()
|
||||
currentServerSetting!!.allowSelfSignedCertificate = selfSignedSwitch!!.isChecked
|
||||
currentServerSetting!!.forcePlainTextPassword = ldapSwitch!!.isChecked
|
||||
currentServerSetting!!.forcePlainTextPassword = plaintextSwitch!!.isChecked
|
||||
currentServerSetting!!.jukeboxByDefault = jukeboxSwitch!!.isChecked
|
||||
}
|
||||
|
||||
@ -354,7 +354,7 @@ class EditServerFragment : Fragment(), OnBackPressedHandler {
|
||||
currentServerSetting!!.userName != userNameEditText!!.editText?.text.toString() ||
|
||||
currentServerSetting!!.password != passwordEditText!!.editText?.text.toString() ||
|
||||
currentServerSetting!!.allowSelfSignedCertificate != selfSignedSwitch!!.isChecked ||
|
||||
currentServerSetting!!.forcePlainTextPassword != ldapSwitch!!.isChecked ||
|
||||
currentServerSetting!!.forcePlainTextPassword != plaintextSwitch!!.isChecked ||
|
||||
currentServerSetting!!.jukeboxByDefault != jukeboxSwitch!!.isChecked
|
||||
}
|
||||
|
||||
|
@ -86,9 +86,9 @@ class NowPlayingFragment : Fragment() {
|
||||
private fun update() {
|
||||
try {
|
||||
if (mediaPlayerController.isPlaying) {
|
||||
playButton!!.setIconResource(R.drawable.media_pause_normal)
|
||||
playButton!!.setIconResource(R.drawable.media_pause)
|
||||
} else {
|
||||
playButton!!.setIconResource(R.drawable.media_start_normal)
|
||||
playButton!!.setIconResource(R.drawable.media_start)
|
||||
}
|
||||
|
||||
val file = mediaPlayerController.currentMediaItem?.toTrack()
|
||||
|
@ -838,13 +838,11 @@ class PlayerFragment :
|
||||
viewAdapter.register(
|
||||
TrackViewBinder(
|
||||
onItemClick = clickHandler,
|
||||
onContextMenuClick = { menu, id -> onContextMenuItemSelected(menu, id) },
|
||||
checkable = false,
|
||||
draggable = true,
|
||||
context = requireContext(),
|
||||
lifecycleOwner = viewLifecycleOwner,
|
||||
createContextMenu = { view, track -> onCreateContextMenu(view, track) },
|
||||
onContextMenuClick = { menu, id -> onContextMenuItemSelected(menu, id) },
|
||||
).apply {
|
||||
) { view, track -> onCreateContextMenu(view, track) }.apply {
|
||||
this.startDrag = { holder ->
|
||||
dragTouchHelper.startDrag(holder)
|
||||
}
|
||||
|
@ -120,7 +120,6 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
|
||||
onContextMenuClick = ::onContextMenuItemSelected,
|
||||
checkable = false,
|
||||
draggable = false,
|
||||
context = requireContext(),
|
||||
lifecycleOwner = viewLifecycleOwner
|
||||
)
|
||||
)
|
||||
|
@ -63,7 +63,6 @@ class ServerSelectorFragment : Fragment() {
|
||||
listView?.adapter = serverRowAdapter
|
||||
|
||||
listView?.onItemClickListener = AdapterView.OnItemClickListener { parent, _, position, _ ->
|
||||
|
||||
val server = parent.getItemAtPosition(position) as ServerSetting
|
||||
ActiveServerProvider.setActiveServerById(server.id)
|
||||
findNavController().popBackStack(R.id.mainFragment, false)
|
||||
|
@ -133,7 +133,6 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
|
||||
onContextMenuClick = { menu, id -> onContextMenuItemSelected(menu, id) },
|
||||
checkable = true,
|
||||
draggable = false,
|
||||
context = requireContext(),
|
||||
lifecycleOwner = viewLifecycleOwner
|
||||
)
|
||||
)
|
||||
|
@ -16,7 +16,6 @@ import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import org.moire.ultrasonic.BuildConfig
|
||||
import org.moire.ultrasonic.R
|
||||
import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient
|
||||
import org.moire.ultrasonic.api.subsonic.throwOnFailure
|
||||
@ -46,7 +45,7 @@ class ImageLoader(
|
||||
.addRequestHandler(AvatarRequestHandler(apiClient))
|
||||
.memoryCache(LruCache(calculateMemoryCacheSize(context)))
|
||||
.build().apply {
|
||||
setIndicatorsEnabled(BuildConfig.DEBUG)
|
||||
// setIndicatorsEnabled(BuildConfig.DEBUG)
|
||||
}
|
||||
|
||||
private fun load(request: ImageRequest) = when (request) {
|
||||
|
@ -1203,7 +1203,7 @@ class AutoMediaBrowserCallback(var player: Player, val libraryService: MediaLibr
|
||||
mediaId,
|
||||
null,
|
||||
false,
|
||||
icon = R.drawable.media_start_normal
|
||||
icon = R.drawable.media_start
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,8 @@ import org.moire.ultrasonic.activity.NavigationActivity
|
||||
import org.moire.ultrasonic.app.UApp
|
||||
import org.moire.ultrasonic.audiofx.EqualizerController
|
||||
import org.moire.ultrasonic.data.ActiveServerProvider
|
||||
import org.moire.ultrasonic.domain.Track
|
||||
import org.moire.ultrasonic.provider.UltrasonicAppWidgetProvider
|
||||
import org.moire.ultrasonic.service.DownloadService
|
||||
import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService
|
||||
import org.moire.ultrasonic.service.RxBus
|
||||
@ -172,6 +174,12 @@ class PlaybackService : MediaLibraryService(), KoinComponent {
|
||||
}
|
||||
|
||||
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
|
||||
updateWidgetTrack(mediaItem?.toTrack())
|
||||
cacheNextSongs()
|
||||
}
|
||||
|
||||
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
||||
updateWidgetPlayerState(isPlaying)
|
||||
cacheNextSongs()
|
||||
}
|
||||
}
|
||||
@ -205,4 +213,14 @@ class PlaybackService : MediaLibraryService(), KoinComponent {
|
||||
.setContentType(C.AUDIO_CONTENT_TYPE_MUSIC)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun updateWidgetTrack(song: Track?) {
|
||||
val context = UApp.applicationContext()
|
||||
UltrasonicAppWidgetProvider.notifyTrackChange(context, song)
|
||||
}
|
||||
|
||||
private fun updateWidgetPlayerState(isPlaying: Boolean) {
|
||||
val context = UApp.applicationContext()
|
||||
UltrasonicAppWidgetProvider.notifyPlayerStateChange(context, isPlaying)
|
||||
}
|
||||
}
|
||||
|
@ -14,10 +14,12 @@ import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.view.KeyEvent
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.widget.RemoteViews
|
||||
import java.lang.Exception
|
||||
import org.moire.ultrasonic.R
|
||||
import org.moire.ultrasonic.activity.NavigationActivity
|
||||
import org.moire.ultrasonic.domain.Track
|
||||
@ -27,141 +29,197 @@ import org.moire.ultrasonic.util.Constants
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Widget Provider for the Ultrasonic Widgets
|
||||
* Widget Provider for the Ultrasonic Widget
|
||||
*/
|
||||
@Suppress("MagicNumber")
|
||||
open class UltrasonicAppWidgetProvider : AppWidgetProvider() {
|
||||
@JvmField
|
||||
protected var layoutId = 0
|
||||
|
||||
override fun onUpdate(
|
||||
context: Context,
|
||||
appWidgetManager: AppWidgetManager,
|
||||
appWidgetIds: IntArray
|
||||
) {
|
||||
defaultAppWidget(context, appWidgetIds)
|
||||
updateTrackAndState(context, appWidgetIds)
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize given widgets to default state, where we launch Ultrasonic on default click
|
||||
* and hide actions if service not running.
|
||||
*/
|
||||
private fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
|
||||
val res = context.resources
|
||||
val views = RemoteViews(context.packageName, layoutId)
|
||||
views.setTextViewText(R.id.title, null)
|
||||
views.setTextViewText(R.id.album, null)
|
||||
views.setTextViewText(R.id.artist, res.getText(R.string.widget_initial_text))
|
||||
linkButtons(context, views, false)
|
||||
pushUpdate(context, appWidgetIds, views)
|
||||
}
|
||||
|
||||
private fun pushUpdate(context: Context, appWidgetIds: IntArray?, views: RemoteViews) {
|
||||
// Update specific list of appWidgetIds if given, otherwise default to all
|
||||
val manager = AppWidgetManager.getInstance(context)
|
||||
if (manager != null) {
|
||||
if (appWidgetIds != null) {
|
||||
manager.updateAppWidget(appWidgetIds, views)
|
||||
} else {
|
||||
manager.updateAppWidget(ComponentName(context, this.javaClass), views)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a change notification coming over from [MediaPlayerController]
|
||||
*/
|
||||
fun notifyChange(context: Context, currentSong: Track?, playing: Boolean, setAlbum: Boolean) {
|
||||
if (hasInstances(context)) {
|
||||
performUpdate(context, currentSong, playing, setAlbum)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check against [AppWidgetManager] if there are any instances of this widget.
|
||||
*/
|
||||
private fun hasInstances(context: Context): Boolean {
|
||||
val manager = AppWidgetManager.getInstance(context)
|
||||
if (manager != null) {
|
||||
val appWidgetIds = manager.getAppWidgetIds(ComponentName(context, javaClass))
|
||||
return appWidgetIds.isNotEmpty()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all active widget instances by pushing changes
|
||||
*/
|
||||
private fun performUpdate(
|
||||
context: Context,
|
||||
currentSong: Track?,
|
||||
playing: Boolean,
|
||||
setAlbum: Boolean
|
||||
override fun onAppWidgetOptionsChanged(
|
||||
context: Context?,
|
||||
appWidgetManager: AppWidgetManager?,
|
||||
appWidgetId: Int,
|
||||
newOptions: Bundle?
|
||||
) {
|
||||
Timber.d("Updating Widget")
|
||||
val res = context.resources
|
||||
val views = RemoteViews(context.packageName, layoutId)
|
||||
val title = currentSong?.title
|
||||
val artist = currentSong?.artist
|
||||
val album = currentSong?.album
|
||||
var errorState: CharSequence? = null
|
||||
|
||||
// Show error message?
|
||||
val status = Environment.getExternalStorageState()
|
||||
if (status == Environment.MEDIA_SHARED || status == Environment.MEDIA_UNMOUNTED) {
|
||||
errorState = res.getText(R.string.widget_sdcard_busy)
|
||||
} else if (status == Environment.MEDIA_REMOVED) {
|
||||
errorState = res.getText(R.string.widget_sdcard_missing)
|
||||
} else if (currentSong == null) {
|
||||
errorState = res.getText(R.string.widget_initial_text)
|
||||
}
|
||||
if (errorState != null) {
|
||||
// Show error state to user
|
||||
views.setTextViewText(R.id.title, null)
|
||||
views.setTextViewText(R.id.artist, errorState)
|
||||
if (setAlbum) {
|
||||
views.setTextViewText(R.id.album, null)
|
||||
}
|
||||
views.setImageViewResource(R.id.appwidget_coverart, R.drawable.unknown_album)
|
||||
} else {
|
||||
// No error, so show normal titles
|
||||
views.setTextViewText(R.id.title, title)
|
||||
views.setTextViewText(R.id.artist, artist)
|
||||
if (setAlbum) {
|
||||
views.setTextViewText(R.id.album, album)
|
||||
}
|
||||
}
|
||||
|
||||
// Set correct drawable for pause state
|
||||
if (playing) {
|
||||
views.setImageViewResource(R.id.control_play, R.drawable.media_pause_normal)
|
||||
} else {
|
||||
views.setImageViewResource(R.id.control_play, R.drawable.media_start_normal)
|
||||
}
|
||||
|
||||
// Set the cover art
|
||||
try {
|
||||
val bitmap =
|
||||
if (currentSong == null) null else BitmapUtils.getAlbumArtBitmapFromDisk(
|
||||
currentSong,
|
||||
240
|
||||
)
|
||||
if (bitmap == null) {
|
||||
// Set default cover art
|
||||
views.setImageViewResource(R.id.appwidget_coverart, R.drawable.unknown_album)
|
||||
} else {
|
||||
views.setImageViewBitmap(R.id.appwidget_coverart, bitmap)
|
||||
}
|
||||
} catch (all: Exception) {
|
||||
Timber.e(all, "Failed to load cover art")
|
||||
views.setImageViewResource(R.id.appwidget_coverart, R.drawable.unknown_album)
|
||||
}
|
||||
|
||||
// Link actions buttons to intents
|
||||
linkButtons(context, views, currentSong != null)
|
||||
pushUpdate(context, null, views)
|
||||
updateTrackAndState(context!!, intArrayOf(appWidgetId))
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private var isPlaying: Boolean = false
|
||||
private var track: Track? = null
|
||||
|
||||
/**
|
||||
* Pushes the current track details to the widgets
|
||||
*/
|
||||
fun notifyTrackChange(context: Context, currentSong: Track?) {
|
||||
this.track = currentSong
|
||||
if (hasInstances(context)) {
|
||||
// The widget won't update correctly if only the track or the state is updated
|
||||
updateTrackAndState(context, null)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes the current player state to the widgets
|
||||
*/
|
||||
fun notifyPlayerStateChange(context: Context, isPlaying: Boolean) {
|
||||
this.isPlaying = isPlaying
|
||||
if (hasInstances(context)) {
|
||||
// The widget won't update correctly if only the track or the state is updated
|
||||
updateTrackAndState(context, null)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the track and the player state to the widgets
|
||||
*/
|
||||
private fun updateTrackAndState(context: Context, appWidgetIds: IntArray? = null) {
|
||||
pushUpdate(context, appWidgetIds) {
|
||||
updateTrack(context, it, track)
|
||||
updatePlayerState(it, isPlaying)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the instances of the widget, and pushes the update to them
|
||||
*/
|
||||
private fun pushUpdate(
|
||||
context: Context,
|
||||
appWidgetIds: IntArray? = null,
|
||||
update: (RemoteViews) -> Unit
|
||||
) {
|
||||
val manager = AppWidgetManager.getInstance(context)
|
||||
if (manager != null) {
|
||||
val widgetIds =
|
||||
appWidgetIds ?: manager.getAppWidgetIds(
|
||||
ComponentName(
|
||||
context,
|
||||
UltrasonicAppWidgetProvider::class.java
|
||||
)
|
||||
)
|
||||
|
||||
widgetIds.forEach {
|
||||
val widgetOptions = manager.getAppWidgetOptions(it)
|
||||
val minHeight =
|
||||
widgetOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT)
|
||||
val minWidth =
|
||||
widgetOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)
|
||||
val layoutId = getLayout(minHeight, minWidth)
|
||||
val views = RemoteViews(context.packageName, layoutId)
|
||||
update(views)
|
||||
manager.updateAppWidget(it, views)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the layout to be displayed for the widget height
|
||||
*/
|
||||
private fun getLayout(height: Int, width: Int): Int {
|
||||
val portrait = (width / height.toFloat()) < 1.8F
|
||||
if (portrait) return R.layout.appwidget_portrait
|
||||
if (height > 100) return R.layout.appwidget_landscape
|
||||
return R.layout.appwidget_landscape_small
|
||||
}
|
||||
|
||||
/**
|
||||
* Check against [AppWidgetManager] if there are any instances of this widget.
|
||||
*/
|
||||
private fun hasInstances(context: Context): Boolean {
|
||||
val manager = AppWidgetManager.getInstance(context)
|
||||
if (manager != null) {
|
||||
val appWidgetIds = manager.getAppWidgetIds(
|
||||
ComponentName(
|
||||
context,
|
||||
UltrasonicAppWidgetProvider::class.java
|
||||
)
|
||||
)
|
||||
return appWidgetIds.isNotEmpty()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Player state in widgets
|
||||
*/
|
||||
private fun updatePlayerState(views: RemoteViews, isPlaying: Boolean) {
|
||||
if (isPlaying) {
|
||||
views.setImageViewResource(R.id.control_play, R.drawable.media_pause)
|
||||
} else {
|
||||
views.setImageViewResource(R.id.control_play, R.drawable.media_start)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Track details in widgets
|
||||
*/
|
||||
private fun updateTrack(
|
||||
context: Context,
|
||||
views: RemoteViews,
|
||||
currentSong: Track?
|
||||
) {
|
||||
Timber.d("Updating Widget")
|
||||
val res = context.resources
|
||||
val title = currentSong?.title
|
||||
val artist = currentSong?.artist
|
||||
val album = currentSong?.album
|
||||
var errorState: CharSequence? = null
|
||||
|
||||
// Show error message?
|
||||
val status = Environment.getExternalStorageState()
|
||||
if (status == Environment.MEDIA_SHARED || status == Environment.MEDIA_UNMOUNTED) {
|
||||
errorState = res.getText(R.string.widget_sdcard_busy)
|
||||
} else if (status == Environment.MEDIA_REMOVED) {
|
||||
errorState = res.getText(R.string.widget_sdcard_missing)
|
||||
} else if (currentSong == null) {
|
||||
errorState = res.getText(R.string.widget_initial_text)
|
||||
}
|
||||
if (errorState != null) {
|
||||
// Show error state to user
|
||||
views.setViewVisibility(R.id.title, GONE)
|
||||
views.setViewVisibility(R.id.album, GONE)
|
||||
views.setTextViewText(R.id.artist, res.getText(R.string.widget_initial_text))
|
||||
views.setBoolean(R.id.artist, "setSingleLine", false)
|
||||
views.setImageViewResource(R.id.appwidget_coverart, R.drawable.unknown_album)
|
||||
} else {
|
||||
// No error, so show normal titles
|
||||
views.setTextViewText(R.id.title, title)
|
||||
views.setTextViewText(R.id.artist, artist)
|
||||
views.setTextViewText(R.id.album, album)
|
||||
views.setBoolean(R.id.artist, "setSingleLine", true)
|
||||
views.setViewVisibility(R.id.title, VISIBLE)
|
||||
views.setViewVisibility(R.id.album, VISIBLE)
|
||||
}
|
||||
// Set the cover art
|
||||
try {
|
||||
val bitmap =
|
||||
if (currentSong == null) null else BitmapUtils.getAlbumArtBitmapFromDisk(
|
||||
currentSong,
|
||||
240
|
||||
)
|
||||
if (bitmap == null) {
|
||||
// Set default cover art
|
||||
views.setImageViewResource(R.id.appwidget_coverart, R.drawable.unknown_album)
|
||||
} else {
|
||||
views.setImageViewBitmap(R.id.appwidget_coverart, bitmap)
|
||||
}
|
||||
} catch (all: Exception) {
|
||||
Timber.e(all, "Failed to load cover art")
|
||||
views.setImageViewResource(R.id.appwidget_coverart, R.drawable.unknown_album)
|
||||
}
|
||||
|
||||
// Link actions buttons to intents
|
||||
linkButtons(context, views, currentSong != null)
|
||||
}
|
||||
|
||||
/**
|
||||
* Link up various button actions using [PendingIntent].
|
||||
*/
|
||||
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* UltrasonicAppWidgetProvider4X1.kt
|
||||
* Copyright (C) 2009-2022 Ultrasonic developers
|
||||
*
|
||||
* Distributed under terms of the GNU GPLv3 license.
|
||||
*/
|
||||
|
||||
package org.moire.ultrasonic.provider
|
||||
|
||||
import org.moire.ultrasonic.R
|
||||
|
||||
class UltrasonicAppWidgetProvider4X1 : UltrasonicAppWidgetProvider() {
|
||||
companion object {
|
||||
@get:Synchronized
|
||||
var instance: UltrasonicAppWidgetProvider4X1? = null
|
||||
get() {
|
||||
if (field == null) {
|
||||
field = UltrasonicAppWidgetProvider4X1()
|
||||
}
|
||||
return field
|
||||
}
|
||||
private set
|
||||
}
|
||||
|
||||
init {
|
||||
layoutId = R.layout.appwidget4x1
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* UltrasonicAppWidgetProvider4X2.kt
|
||||
* Copyright (C) 2009-2022 Ultrasonic developers
|
||||
*
|
||||
* Distributed under terms of the GNU GPLv3 license.
|
||||
*/
|
||||
|
||||
package org.moire.ultrasonic.provider
|
||||
|
||||
import org.moire.ultrasonic.R
|
||||
|
||||
class UltrasonicAppWidgetProvider4X2 : UltrasonicAppWidgetProvider() {
|
||||
companion object {
|
||||
@get:Synchronized
|
||||
var instance: UltrasonicAppWidgetProvider4X2? = null
|
||||
get() {
|
||||
if (field == null) {
|
||||
field = UltrasonicAppWidgetProvider4X2()
|
||||
}
|
||||
return field
|
||||
}
|
||||
private set
|
||||
}
|
||||
|
||||
init {
|
||||
layoutId = R.layout.appwidget4x2
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* UltrasonicAppWidgetProvider4X3.kt
|
||||
* Copyright (C) 2009-2022 Ultrasonic developers
|
||||
*
|
||||
* Distributed under terms of the GNU GPLv3 license.
|
||||
*/
|
||||
|
||||
package org.moire.ultrasonic.provider
|
||||
|
||||
import org.moire.ultrasonic.R
|
||||
|
||||
class UltrasonicAppWidgetProvider4X3 : UltrasonicAppWidgetProvider() {
|
||||
companion object {
|
||||
@get:Synchronized
|
||||
var instance: UltrasonicAppWidgetProvider4X3? = null
|
||||
get() {
|
||||
if (field == null) {
|
||||
field = UltrasonicAppWidgetProvider4X3()
|
||||
}
|
||||
return field
|
||||
}
|
||||
private set
|
||||
}
|
||||
|
||||
init {
|
||||
layoutId = R.layout.appwidget4x3
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* UltrasonicAppWidgetProvider4X4.kt
|
||||
* Copyright (C) 2009-2022 Ultrasonic developers
|
||||
*
|
||||
* Distributed under terms of the GNU GPLv3 license.
|
||||
*/
|
||||
|
||||
package org.moire.ultrasonic.provider
|
||||
|
||||
import org.moire.ultrasonic.R
|
||||
|
||||
class UltrasonicAppWidgetProvider4X4 : UltrasonicAppWidgetProvider() {
|
||||
companion object {
|
||||
@get:Synchronized
|
||||
var instance: UltrasonicAppWidgetProvider4X4? = null
|
||||
get() {
|
||||
if (field == null) {
|
||||
field = UltrasonicAppWidgetProvider4X4()
|
||||
}
|
||||
return field
|
||||
}
|
||||
private set
|
||||
}
|
||||
|
||||
init {
|
||||
layoutId = R.layout.appwidget4x4
|
||||
}
|
||||
}
|
@ -36,10 +36,6 @@ import org.moire.ultrasonic.data.ActiveServerProvider
|
||||
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.OFFLINE_DB_ID
|
||||
import org.moire.ultrasonic.domain.Track
|
||||
import org.moire.ultrasonic.playback.PlaybackService
|
||||
import org.moire.ultrasonic.provider.UltrasonicAppWidgetProvider4X1
|
||||
import org.moire.ultrasonic.provider.UltrasonicAppWidgetProvider4X2
|
||||
import org.moire.ultrasonic.provider.UltrasonicAppWidgetProvider4X3
|
||||
import org.moire.ultrasonic.provider.UltrasonicAppWidgetProvider4X4
|
||||
import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService
|
||||
import org.moire.ultrasonic.util.MainThreadExecutor
|
||||
import org.moire.ultrasonic.util.Settings
|
||||
@ -201,11 +197,6 @@ class MediaPlayerController(
|
||||
}
|
||||
}
|
||||
|
||||
rxBusSubscription += RxBus.stopServiceCommandObservable.subscribe {
|
||||
// Clear the widget when we stop the service
|
||||
updateWidget(null)
|
||||
}
|
||||
|
||||
rxBusSubscription += RxBus.shutdownCommandObservable.subscribe {
|
||||
playbackStateSerializer.serializeNow(
|
||||
playlist.map { it.toTrack() },
|
||||
@ -236,9 +227,6 @@ class MediaPlayerController(
|
||||
scrobbler.scrobble(currentPlaying, true)
|
||||
}
|
||||
}
|
||||
|
||||
// Update widget
|
||||
updateWidget(currentPlaying)
|
||||
}
|
||||
|
||||
private fun clearBookmark() {
|
||||
@ -267,15 +255,6 @@ class MediaPlayerController(
|
||||
Timber.i("New PlaybackState: %s", newState)
|
||||
}
|
||||
|
||||
private fun updateWidget(song: Track?) {
|
||||
val context = UApp.applicationContext()
|
||||
|
||||
UltrasonicAppWidgetProvider4X1.instance?.notifyChange(context, song, isPlaying, false)
|
||||
UltrasonicAppWidgetProvider4X2.instance?.notifyChange(context, song, isPlaying, true)
|
||||
UltrasonicAppWidgetProvider4X3.instance?.notifyChange(context, song, isPlaying, true)
|
||||
UltrasonicAppWidgetProvider4X4.instance?.notifyChange(context, song, isPlaying, true)
|
||||
}
|
||||
|
||||
fun onDestroy() {
|
||||
if (!created) return
|
||||
|
||||
|
@ -8,29 +8,45 @@
|
||||
package org.moire.ultrasonic.util
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import org.moire.ultrasonic.R
|
||||
import com.google.android.material.color.MaterialColors
|
||||
|
||||
private const val LUMINANCE_LIMIT = 0.5
|
||||
private const val LUMINANCE_CORRECTION = -0.25
|
||||
|
||||
/**
|
||||
* Contains functions for computing server display colors
|
||||
*/
|
||||
object ServerColor {
|
||||
|
||||
@ColorInt
|
||||
fun getBackgroundColor(context: Context, serverColor: Int?): Int {
|
||||
return serverColor ?: ContextCompat.getColor(
|
||||
context, Util.getResourceFromAttribute(context, R.attr.colorPrimary)
|
||||
)
|
||||
return if (serverColor != null) {
|
||||
MaterialColors.harmonizeWithPrimary(context, serverColor)
|
||||
} else {
|
||||
MaterialColors.getColor(context, android.R.attr.colorPrimary, "")
|
||||
}
|
||||
}
|
||||
|
||||
fun getForegroundColor(context: Context, serverColor: Int?): Int {
|
||||
@ColorInt
|
||||
fun getForegroundColor(
|
||||
context: Context,
|
||||
serverColor: Int?,
|
||||
showVectorBackground: Boolean = false
|
||||
): Int {
|
||||
val backgroundColor = getBackgroundColor(context, serverColor)
|
||||
val luminance = ColorUtils.calculateLuminance(backgroundColor)
|
||||
var luminance = ColorUtils.calculateLuminance(backgroundColor)
|
||||
|
||||
// The actual luminance is a good bit lower
|
||||
// when the background color is being overlayed by the vector
|
||||
if (showVectorBackground) luminance += LUMINANCE_CORRECTION
|
||||
|
||||
return if (luminance < LUMINANCE_LIMIT) {
|
||||
ContextCompat.getColor(context, R.color.selected_menu_dark)
|
||||
ContextCompat.getColor(context, org.moire.ultrasonic.R.color.selected_menu_dark)
|
||||
} else {
|
||||
ContextCompat.getColor(context, R.color.selected_menu_light)
|
||||
ContextCompat.getColor(context, org.moire.ultrasonic.R.color.selected_menu_light)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ object Settings {
|
||||
@JvmStatic
|
||||
var theme by StringSetting(
|
||||
getKey(R.string.setting_key_theme),
|
||||
getKey(R.string.setting_key_theme_dark)
|
||||
getKey(R.string.setting_key_theme_day_night)
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
@ -31,7 +31,6 @@ import android.os.Build
|
||||
import android.os.Environment
|
||||
import android.text.TextUtils
|
||||
import android.util.DisplayMetrics
|
||||
import android.util.TypedValue
|
||||
import android.view.Gravity
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.Toast
|
||||
@ -94,21 +93,13 @@ object Util {
|
||||
fun applyTheme(context: Context?) {
|
||||
if (context == null) return
|
||||
val style = getStyleFromSettings(context)
|
||||
// First set the theme (light, dark, etc.)
|
||||
context.setTheme(style)
|
||||
// Then set an overlay controlling the status bar behaviour etc.
|
||||
context.setTheme(R.style.UltrasonicTheme_Base)
|
||||
}
|
||||
|
||||
private fun getStyleFromSettings(context: Context): Int {
|
||||
// Migration
|
||||
// TODO: Remove in June 2023
|
||||
when (Settings.theme.lowercase()) {
|
||||
"fullscreen" -> {
|
||||
Settings.theme = context.getString(R.string.setting_key_theme_dark)
|
||||
}
|
||||
"fullscreenlight" -> {
|
||||
Settings.theme = context.getString(R.string.setting_key_theme_light)
|
||||
}
|
||||
}
|
||||
|
||||
return when (Settings.theme.lowercase()) {
|
||||
context.getString(R.string.setting_key_theme_dark) -> {
|
||||
R.style.UltrasonicTheme_Dark
|
||||
@ -120,7 +111,7 @@ object Util {
|
||||
R.style.UltrasonicTheme_Light
|
||||
}
|
||||
else -> {
|
||||
R.style.UltrasonicTheme_Dark
|
||||
R.style.UltrasonicTheme_DayNight
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -571,13 +562,6 @@ object Util {
|
||||
)
|
||||
}
|
||||
|
||||
fun getResourceFromAttribute(context: Context, resId: Int): Int {
|
||||
val typedValue = TypedValue()
|
||||
val theme = context.theme
|
||||
theme.resolveAttribute(resId, typedValue, true)
|
||||
return typedValue.resourceId
|
||||
}
|
||||
|
||||
fun isFirstRun(): Boolean {
|
||||
if (Settings.firstRunExecuted) return false
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 889 B |
Binary file not shown.
Before Width: | Height: | Size: 8.6 KiB |
Binary file not shown.
Before Width: | Height: | Size: 12 KiB |
Binary file not shown.
Before Width: | Height: | Size: 16 KiB |
12
ultrasonic/src/main/res/drawable/app_widget_background.xml
Normal file
12
ultrasonic/src/main/res/drawable/app_widget_background.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Background for widgets to make the rounded corners based on the
|
||||
appWidgetRadius attribute value
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle"
|
||||
android:theme="@style/Theme.AppWidget.AppWidgetContainer">
|
||||
|
||||
<corners android:radius="?attr/appWidgetRadius" />
|
||||
<solid android:color="?attr/appWidgetBackground" />
|
||||
</shape>
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<solid android:color="?attr/colorOnPrimary" />
|
||||
<solid android:color="#FFF" />
|
||||
<size
|
||||
android:width="120dp"
|
||||
android:height="120dp"/>
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
<item android:id="@android:id/mask">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="?android:colorAccent" />
|
||||
<solid android:color="?attr/colorSecondary" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
|
@ -2,8 +2,13 @@
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlHighlight">
|
||||
|
||||
<!-- Normally it would be unusal to set the fillColor to something else than #FFF here,
|
||||
but applying the tint seems to take a short moment in the artist list, so setting it already
|
||||
here once avoids a flash of the wrong color -->
|
||||
<path
|
||||
android:fillColor="#AAA"
|
||||
android:fillColor="?attr/colorOnPrimarySurface"
|
||||
android:pathData="M3,5v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2L5,3c-1.11,0 -2,0.9 -2,2zM15,9c0,1.66 -1.34,3 -3,3s-3,-1.34 -3,-3 1.34,-3 3,-3 3,1.34 3,3zM6,17c0,-2 4,-3.1 6,-3.1s6,1.1 6,3.1v1L6,18v-1z"/>
|
||||
</vector>
|
||||
|
@ -5,6 +5,6 @@
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:fillColor="#000"
|
||||
android:pathData="M8,5v14l11,-7z"/>
|
||||
</vector>
|
@ -3,10 +3,10 @@
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners
|
||||
android:topLeftRadius="44dp"
|
||||
android:topRightRadius="44dp"
|
||||
android:bottomRightRadius="44dp"
|
||||
android:bottomLeftRadius="44dp" />
|
||||
android:topLeftRadius="28dp"
|
||||
android:topRightRadius="28dp"
|
||||
android:bottomRightRadius="28dp"
|
||||
android:bottomLeftRadius="28dp" />
|
||||
|
||||
<stroke android:width="2dp" android:color="?attr/colorOnBackground" />
|
||||
<stroke android:width="1dp" android:color="?attr/colorOutline" />
|
||||
</shape>
|
@ -1,17 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="?android:colorControlHighlight">
|
||||
|
||||
<item android:id="@android:id/mask">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="?android:colorAccent" />
|
||||
<solid android:color="?attr/colorSurfaceVariant" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="?attr/color_selected" />
|
||||
<solid android:color="?attr/colorSurfaceVariant" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
@ -1,14 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:pathData="M15,5V3H9v2"/>
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:fillAlpha="150"
|
||||
android:pathData="M9,5V9H5l7,7 7,-7H15V5M5,18v2h14v-2z"/>
|
||||
</vector>
|
@ -1,14 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:pathData="M15,7V3H9v4"/>
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:fillAlpha="150"
|
||||
android:pathData="M9,7V9H5l7,7 7,-7H15V7M5,18v2h14v-2z"/>
|
||||
</vector>
|
@ -1,14 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:pathData="M15,9V3H9v6"/>
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:fillAlpha="150"
|
||||
android:pathData="M9,9H5l7,7 7,-7H15M5,18v2h14v-2z"/>
|
||||
</vector>
|
@ -1,14 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:pathData="M17,11 L19,9H15V3H9V9H5l2,2"/>
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:fillAlpha="150"
|
||||
android:pathData="m7,11 l5,5 5,-5M5,18v2h14v-2z"/>
|
||||
</vector>
|
@ -1,14 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:pathData="M15,13 L19,9H15V3H9V9H5l4,4"/>
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:fillAlpha="150"
|
||||
android:pathData="m9,13 l3,3 3,-3M5,18v2h14v-2z"/>
|
||||
</vector>
|
@ -1,14 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:pathData="M13,15 L19,9H15V3H9V9H5l6,6"/>
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:fillAlpha="150"
|
||||
android:pathData="m11,15 l1,1 1,-1m-8,3v2h14v-2z"/>
|
||||
</vector>
|
@ -1,14 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:pathData="M19,9H15V3H9V9H5l7,7z"/>
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:fillAlpha="150"
|
||||
android:pathData="m5,18v2h14v-2z"/>
|
||||
</vector>
|
14
ultrasonic/src/main/res/drawable/widget_preview.xml
Normal file
14
ultrasonic/src/main/res/drawable/widget_preview.xml
Normal file
@ -0,0 +1,14 @@
|
||||
<vector android:autoMirrored="true" android:height="41.69701dp"
|
||||
android:viewportHeight="41.47" android:viewportWidth="158.93"
|
||||
android:width="159.8dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#B5CAD7"
|
||||
android:pathData="m39.46,0.01h108.88c5.85,0 10.58,4.74 10.58,10.58v20.29c0,5.85 -4.74,10.58 -10.58,10.58L39.46,41.46Z"
|
||||
android:strokeColor="#00000000" android:strokeWidth="0.3"/>
|
||||
<path android:fillColor="#003549"
|
||||
android:pathData="M10.59,0.01L39.46,0.01v41.45L10.59,41.46c-5.85,0 -10.58,-4.74 -10.58,-10.58v-20.29c0,-5.85 4.74,-10.58 10.58,-10.58z"
|
||||
android:strokeColor="#00000000" android:strokeWidth="0.3"/>
|
||||
<path android:fillColor="#F2F4EE"
|
||||
android:pathData="m121.38,11.09 l17.34,10.28 -17.34,10.23z"
|
||||
android:strokeColor="#00000000" android:strokeLineCap="butt"
|
||||
android:strokeLineJoin="miter" android:strokeWidth="0.20238"/>
|
||||
</vector>
|
@ -29,7 +29,7 @@
|
||||
android:layout_weight="1"
|
||||
android:visibility="gone"
|
||||
android:contentDescription="@string/common.play_now"
|
||||
app:icon="@drawable/media_start_normal"
|
||||
app:icon="@drawable/media_start"
|
||||
app:iconGravity="textTop"
|
||||
app:iconSize="26dp" />
|
||||
|
||||
@ -120,7 +120,7 @@
|
||||
android:layout_weight="1"
|
||||
android:visibility="gone"
|
||||
android:contentDescription="@string/search.more"
|
||||
app:icon="@drawable/media_forward_normal"
|
||||
app:icon="@drawable/media_forward"
|
||||
app:iconGravity="textTop"
|
||||
app:iconSize="26dp" />
|
||||
|
||||
|
@ -1,105 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:minWidth="250dp"
|
||||
a:minHeight="40dp"
|
||||
a:background="@drawable/appwidget_dark_bg_trans"
|
||||
a:orientation="horizontal" >
|
||||
|
||||
<ImageView
|
||||
a:id="@+id/appwidget_coverart"
|
||||
a:layout_width="80dp"
|
||||
a:layout_height="80dp"
|
||||
a:layout_gravity="center_vertical"
|
||||
a:clickable="true"
|
||||
a:focusable="true"
|
||||
a:src="@drawable/unknown_album" />
|
||||
|
||||
<LinearLayout
|
||||
a:id="@+id/linearLayout1"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="match_parent"
|
||||
a:orientation="vertical" >
|
||||
|
||||
<LinearLayout
|
||||
a:id="@+id/appwidget_top"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:clickable="true"
|
||||
a:focusable="true"
|
||||
a:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
a:id="@+id/title"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:ellipsize="none"
|
||||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="20dip"
|
||||
a:minHeight="16sp"
|
||||
a:paddingStart="4dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:paddingTop="4dip"
|
||||
a:singleLine="true"
|
||||
a:gravity="center_horizontal"
|
||||
a:text="Title"
|
||||
a:textColor="@color/appwidget_text"
|
||||
a:textSize="16sp"
|
||||
a:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/artist"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:ellipsize="none"
|
||||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="10dip"
|
||||
a:minHeight="12sp"
|
||||
a:paddingBottom="4dip"
|
||||
a:paddingStart="4dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:gravity="center_horizontal"
|
||||
a:text="Artist"
|
||||
a:textColor="@color/appwidget_text"
|
||||
a:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="fill_parent"
|
||||
a:orientation="horizontal"
|
||||
a:paddingBottom="4dip"
|
||||
a:paddingTop="4dip" >
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_previous"
|
||||
a:layout_width="0dip"
|
||||
a:layout_height="fill_parent"
|
||||
a:layout_weight="1"
|
||||
a:background="@color/appwidget_button_background"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/media_backward_normal" />
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_play"
|
||||
a:layout_width="0dip"
|
||||
a:layout_height="fill_parent"
|
||||
a:layout_weight="1"
|
||||
a:background="@color/appwidget_button_background"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/media_start_normal" />
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_next"
|
||||
a:layout_width="0dip"
|
||||
a:layout_height="fill_parent"
|
||||
a:layout_weight="1"
|
||||
a:background="@color/appwidget_button_background"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/media_forward_normal" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@ -1,129 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:minWidth="250dp"
|
||||
a:minHeight="180dp"
|
||||
a:background="@drawable/appwidget_dark_bg_trans"
|
||||
a:orientation="vertical" >
|
||||
|
||||
<ImageView
|
||||
a:id="@+id/appwidget_coverart"
|
||||
a:layout_width="170dp"
|
||||
a:layout_height="170dp"
|
||||
a:layout_gravity="center_horizontal"
|
||||
a:clickable="true"
|
||||
a:focusable="true"
|
||||
a:paddingTop="6dip"
|
||||
a:paddingBottom="6dip"
|
||||
a:src="@drawable/unknown_album" />
|
||||
|
||||
<LinearLayout
|
||||
a:id="@+id/linearLayout1"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:orientation="vertical" >
|
||||
|
||||
<LinearLayout
|
||||
a:id="@+id/appwidget_top"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:clickable="true"
|
||||
a:focusable="true"
|
||||
a:orientation="vertical"
|
||||
a:paddingBottom="4dip"
|
||||
a:paddingTop="4dip" >
|
||||
|
||||
<TextView
|
||||
a:id="@+id/title"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:ellipsize="none"
|
||||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="20dip"
|
||||
a:minHeight="16sp"
|
||||
a:paddingStart="5dip"
|
||||
a:paddingEnd="5dip"
|
||||
a:singleLine="true"
|
||||
a:textColor="@color/appwidget_text"
|
||||
a:textSize="16sp"
|
||||
a:text="Title"
|
||||
a:layout_gravity="center_horizontal"
|
||||
a:gravity="center"
|
||||
a:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/artist"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:ellipsize="none"
|
||||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="10dip"
|
||||
a:minHeight="12sp"
|
||||
a:paddingBottom="2dip"
|
||||
a:paddingStart="5dip"
|
||||
a:singleLine="true"
|
||||
a:text="Artist"
|
||||
a:layout_gravity="center_horizontal"
|
||||
a:gravity="center"
|
||||
a:textColor="@color/appwidget_text"
|
||||
a:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/album"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:ellipsize="none"
|
||||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="10dip"
|
||||
a:minHeight="12sp"
|
||||
a:paddingBottom="2dip"
|
||||
a:paddingStart="5dip"
|
||||
a:singleLine="true"
|
||||
a:text="Album"
|
||||
a:layout_gravity="center_horizontal"
|
||||
a:gravity="center"
|
||||
a:textColor="@color/appwidget_text"
|
||||
a:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_gravity="bottom"
|
||||
a:gravity="bottom"
|
||||
a:orientation="horizontal"
|
||||
a:paddingBottom="4dip"
|
||||
a:paddingTop="4dip" >
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_previous"
|
||||
a:layout_width="0dip"
|
||||
a:layout_height="32dp"
|
||||
a:layout_weight="1"
|
||||
a:background="@color/appwidget_button_background"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/media_backward_normal" />
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_play"
|
||||
a:layout_width="0dip"
|
||||
a:layout_height="32dp"
|
||||
a:layout_weight="1"
|
||||
a:background="@color/appwidget_button_background"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/media_start_normal" />
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_next"
|
||||
a:layout_width="0dip"
|
||||
a:layout_height="32dp"
|
||||
a:layout_weight="1"
|
||||
a:background="@color/appwidget_button_background"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/media_forward_normal" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@ -1,130 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:minWidth="250dp"
|
||||
a:minHeight="250dp"
|
||||
a:orientation="vertical"
|
||||
a:background="@drawable/appwidget_dark_bg_trans" >
|
||||
|
||||
<ImageView
|
||||
a:id="@+id/appwidget_coverart"
|
||||
a:layout_width="234dp"
|
||||
a:layout_height="234dp"
|
||||
a:layout_gravity="center_horizontal"
|
||||
a:clickable="true"
|
||||
a:focusable="true"
|
||||
a:layout_margin="6dip"
|
||||
a:paddingTop="6dip"
|
||||
a:paddingBottom="6dip"
|
||||
a:src="@drawable/unknown_album" />
|
||||
|
||||
<LinearLayout
|
||||
a:id="@+id/linearLayout1"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:orientation="vertical" >
|
||||
|
||||
<LinearLayout
|
||||
a:id="@+id/appwidget_top"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:clickable="true"
|
||||
a:focusable="true"
|
||||
a:orientation="vertical"
|
||||
a:paddingTop="4dip"
|
||||
a:paddingBottom="4dip" >
|
||||
|
||||
<TextView
|
||||
a:id="@+id/title"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:ellipsize="none"
|
||||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="20dip"
|
||||
a:minHeight="16sp"
|
||||
a:paddingStart="5dip"
|
||||
a:paddingEnd="5dip"
|
||||
a:singleLine="true"
|
||||
a:textColor="@color/appwidget_text"
|
||||
a:textSize="16sp"
|
||||
a:text="Title"
|
||||
a:layout_gravity="center_horizontal"
|
||||
a:gravity="center"
|
||||
a:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/artist"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:ellipsize="none"
|
||||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="10dip"
|
||||
a:minHeight="12sp"
|
||||
a:paddingBottom="2dip"
|
||||
a:paddingStart="5dip"
|
||||
a:singleLine="true"
|
||||
a:text="Artist"
|
||||
a:layout_gravity="center_horizontal"
|
||||
a:gravity="center"
|
||||
a:textColor="@color/appwidget_text"
|
||||
a:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/album"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:ellipsize="none"
|
||||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="10dip"
|
||||
a:minHeight="12sp"
|
||||
a:paddingBottom="2dip"
|
||||
a:paddingStart="5dip"
|
||||
a:singleLine="true"
|
||||
a:text="Album"
|
||||
a:layout_gravity="center_horizontal"
|
||||
a:gravity="center"
|
||||
a:textColor="@color/appwidget_text"
|
||||
a:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_gravity="bottom"
|
||||
a:gravity="bottom"
|
||||
a:orientation="horizontal"
|
||||
a:paddingBottom="4dip"
|
||||
a:paddingTop="4dip" >
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_previous"
|
||||
a:layout_width="0dip"
|
||||
a:layout_height="32dp"
|
||||
a:layout_weight="1"
|
||||
a:background="@color/appwidget_button_background"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/media_backward_normal" />
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_play"
|
||||
a:layout_width="0dip"
|
||||
a:layout_height="32dp"
|
||||
a:layout_weight="1"
|
||||
a:background="@color/appwidget_button_background"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/media_start_normal" />
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_next"
|
||||
a:layout_width="0dip"
|
||||
a:layout_height="32dp"
|
||||
a:layout_weight="1"
|
||||
a:background="@color/appwidget_button_background"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/media_forward_normal" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@ -1,26 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
style="@style/Widget.AppWidget.AppWidget.Container"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_height="fill_parent"
|
||||
a:minWidth="250dp"
|
||||
a:minHeight="110dp"
|
||||
a:background="@drawable/appwidget_dark_bg_trans"
|
||||
a:orientation="horizontal" >
|
||||
a:orientation="horizontal"
|
||||
a:theme="@style/Theme.AppWidget.AppWidgetContainerCropped"
|
||||
tools:ignore="UseAppTint">
|
||||
|
||||
<ImageView
|
||||
a:id="@+id/appwidget_coverart"
|
||||
a:layout_width="110dp"
|
||||
a:layout_height="110dp"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="match_parent"
|
||||
a:layout_gravity="center_vertical"
|
||||
a:adjustViewBounds="true"
|
||||
a:clickable="true"
|
||||
a:focusable="true"
|
||||
a:importantForAccessibility="no"
|
||||
a:scaleType="fitXY"
|
||||
a:src="@drawable/unknown_album" />
|
||||
|
||||
<LinearLayout
|
||||
a:id="@+id/linearLayout1"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="match_parent"
|
||||
a:orientation="vertical" >
|
||||
a:layout_gravity="center_vertical"
|
||||
a:layout_marginHorizontal="5dp"
|
||||
a:gravity="center"
|
||||
a:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
a:id="@+id/appwidget_top"
|
||||
@ -28,98 +37,88 @@
|
||||
a:layout_height="wrap_content"
|
||||
a:clickable="true"
|
||||
a:focusable="true"
|
||||
a:orientation="vertical"
|
||||
a:paddingTop="4dip"
|
||||
a:paddingBottom="4dip" >
|
||||
a:gravity="center"
|
||||
a:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
a:id="@+id/title"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:ellipsize="none"
|
||||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="20dip"
|
||||
a:gravity="center_horizontal"
|
||||
a:minHeight="16sp"
|
||||
a:paddingStart="4dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:paddingTop="4dip"
|
||||
a:singleLine="true"
|
||||
a:gravity="center_horizontal"
|
||||
a:text="Title"
|
||||
a:textColor="@color/appwidget_text"
|
||||
a:textSize="16sp"
|
||||
a:textStyle="bold" />
|
||||
a:paddingEnd="4dip"
|
||||
a:textAppearance="@style/TextAppearance.Material3.TitleMedium"
|
||||
tools:text="Title" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/artist"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:ellipsize="none"
|
||||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="10dip"
|
||||
a:gravity="center_horizontal"
|
||||
a:minHeight="12sp"
|
||||
a:paddingStart="4dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:gravity="center_horizontal"
|
||||
a:text="Artist"
|
||||
a:textColor="@color/appwidget_text"
|
||||
a:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
a:textAppearance="@style/TextAppearance.Material3.BodyLarge"
|
||||
tools:text="Artist" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/album"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:ellipsize="none"
|
||||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="10dip"
|
||||
a:gravity="center_horizontal"
|
||||
a:minHeight="12sp"
|
||||
a:paddingBottom="4dip"
|
||||
a:paddingStart="4dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:gravity="center_horizontal"
|
||||
a:text="Album"
|
||||
a:textColor="@color/appwidget_text"
|
||||
a:textSize="12sp" />
|
||||
|
||||
a:textAppearance="@style/TextAppearance.Material3.BodyLarge"
|
||||
tools:text="Album" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:orientation="horizontal"
|
||||
a:layout_gravity="bottom"
|
||||
a:gravity="bottom"
|
||||
a:paddingBottom="4dip"
|
||||
a:paddingTop="4dip" >
|
||||
a:orientation="horizontal"
|
||||
a:paddingTop="4dip"
|
||||
a:paddingBottom="4dip">
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_previous"
|
||||
a:layout_width="0dip"
|
||||
a:layout_height="32dp"
|
||||
a:layout_weight="1"
|
||||
a:background="@color/appwidget_button_background"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/media_backward_normal" />
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="40dp"
|
||||
a:layout_gravity="center"
|
||||
a:layout_weight="0.6"
|
||||
a:importantForAccessibility="no"
|
||||
a:src="@drawable/media_backward"
|
||||
/>
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_play"
|
||||
a:layout_width="0dip"
|
||||
a:layout_height="32dp"
|
||||
a:theme="@style/Theme.AppWidget.ImageButton"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="70dp"
|
||||
a:layout_gravity="center"
|
||||
a:layout_weight="1"
|
||||
a:background="@color/appwidget_button_background"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/media_start_normal" />
|
||||
a:importantForAccessibility="no"
|
||||
a:src="@drawable/media_start"
|
||||
/>
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_next"
|
||||
a:layout_width="0dip"
|
||||
a:layout_height="32dp"
|
||||
a:layout_weight="1"
|
||||
a:background="@color/appwidget_button_background"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/media_forward_normal" />
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="40dp"
|
||||
a:layout_gravity="center"
|
||||
a:layout_weight="0.6"
|
||||
a:importantForAccessibility="no"
|
||||
a:src="@drawable/media_forward"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
112
ultrasonic/src/main/res/layout/appwidget_landscape_small.xml
Normal file
112
ultrasonic/src/main/res/layout/appwidget_landscape_small.xml
Normal file
@ -0,0 +1,112 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
style="@style/Widget.AppWidget.AppWidget.Container"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:minWidth="220dp"
|
||||
a:minHeight="80dp"
|
||||
a:orientation="horizontal"
|
||||
a:theme="@style/Theme.AppWidget.AppWidgetContainerCropped"
|
||||
tools:ignore="UseAppTint,NestedWeights"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
a:id="@+id/appwidget_coverart"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="match_parent"
|
||||
a:layout_gravity="center_vertical"
|
||||
a:layout_margin="0dp"
|
||||
a:adjustViewBounds="true"
|
||||
a:clickable="true"
|
||||
a:focusable="true"
|
||||
a:importantForAccessibility="no"
|
||||
a:maxWidth="150dp"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/unknown_album" />
|
||||
|
||||
<LinearLayout
|
||||
a:id="@+id/linearLayout1"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="match_parent"
|
||||
a:layout_marginHorizontal="5dp"
|
||||
a:orientation="horizontal"
|
||||
a:padding="12dp"
|
||||
a:baselineAligned="false">
|
||||
|
||||
<LinearLayout
|
||||
a:id="@+id/appwidget_top"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="fill_parent"
|
||||
a:layout_weight="1"
|
||||
a:clickable="true"
|
||||
a:focusable="true"
|
||||
a:gravity="center_vertical"
|
||||
a:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
a:id="@+id/title"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_weight="1"
|
||||
a:ellipsize="marquee"
|
||||
a:gravity="bottom"
|
||||
a:textAppearance="@style/TextAppearance.Material3.TitleMedium"
|
||||
tools:text="Title"
|
||||
/>
|
||||
|
||||
|
||||
<TextView
|
||||
a:id="@+id/artist"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_weight="1"
|
||||
a:ellipsize="marquee"
|
||||
a:gravity="left"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="@style/TextAppearance.Material3.BodyLarge"
|
||||
tools:text="Artist" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="match_parent"
|
||||
a:layout_weight="1"
|
||||
a:gravity="end">
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_previous"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="match_parent"
|
||||
a:layout_weight="0.6"
|
||||
a:importantForAccessibility="no"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/media_backward"
|
||||
a:background="@null"
|
||||
/>
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_play"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="match_parent"
|
||||
a:layout_weight="1"
|
||||
a:importantForAccessibility="no"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/media_start"
|
||||
a:background="@null"/>
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_next"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="match_parent"
|
||||
a:layout_weight="0.6"
|
||||
a:importantForAccessibility="no"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/media_forward"
|
||||
a:background="@null"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
128
ultrasonic/src/main/res/layout/appwidget_portrait.xml
Normal file
128
ultrasonic/src/main/res/layout/appwidget_portrait.xml
Normal file
@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="fill_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
a:minWidth="250dp"
|
||||
a:minHeight="180dp"
|
||||
style="@style/Widget.AppWidget.AppWidget.Container"
|
||||
a:theme="@style/Theme.AppWidget.AppWidgetContainerCropped"
|
||||
a:orientation="vertical"
|
||||
tools:ignore="UseAppTint">
|
||||
|
||||
<ImageView
|
||||
a:id="@+id/appwidget_coverart"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_gravity="center_horizontal"
|
||||
a:layout_alignParentTop="true"
|
||||
a:layout_above="@id/linearLayout1"
|
||||
a:scaleType="centerCrop"
|
||||
a:adjustViewBounds="true"
|
||||
a:clickable="true"
|
||||
a:focusable="true"
|
||||
a:importantForAccessibility="no"
|
||||
a:clipToOutline="true"
|
||||
a:src="@drawable/unknown_album"
|
||||
tools:ignore="UnusedAttribute" />
|
||||
|
||||
<LinearLayout
|
||||
a:id="@+id/linearLayout1"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_above="@id/layout_buttons"
|
||||
a:paddingVertical="6dp"
|
||||
a:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
a:id="@+id/title"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:ellipsize="none"
|
||||
a:minHeight="16sp"
|
||||
a:paddingStart="5dip"
|
||||
a:paddingEnd="5dip"
|
||||
a:textAppearance="@style/TextAppearance.Material3.TitleMedium"
|
||||
tools:text="Title"
|
||||
a:layout_gravity="center_horizontal"
|
||||
a:gravity="center"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
a:id="@+id/artist"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:ellipsize="none"
|
||||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="10dip"
|
||||
a:minHeight="12sp"
|
||||
a:paddingBottom="2dip"
|
||||
a:paddingStart="5dip"
|
||||
a:singleLine="true"
|
||||
tools:text="Artist"
|
||||
a:layout_gravity="center_horizontal"
|
||||
a:gravity="center"
|
||||
a:textAppearance="@style/TextAppearance.Material3.BodyLarge" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/album"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:ellipsize="none"
|
||||
a:fadingEdge="horizontal"
|
||||
a:fadingEdgeLength="10dip"
|
||||
a:minHeight="12sp"
|
||||
a:paddingBottom="2dip"
|
||||
a:paddingStart="5dip"
|
||||
a:singleLine="true"
|
||||
tools:text="Album"
|
||||
a:layout_gravity="center_horizontal"
|
||||
a:gravity="center"
|
||||
a:textAppearance="@style/TextAppearance.Material3.BodyLarge" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
a:id="@+id/layout_buttons"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_alignParentBottom="true"
|
||||
a:layout_gravity="bottom"
|
||||
a:gravity="bottom"
|
||||
a:orientation="horizontal"
|
||||
a:paddingTop="2dip"
|
||||
a:paddingBottom="4dip">
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_previous"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="40dp"
|
||||
a:layout_gravity="center"
|
||||
a:layout_weight="0.6"
|
||||
a:scaleType="fitCenter"
|
||||
a:importantForAccessibility="no"
|
||||
a:src="@drawable/media_backward"
|
||||
/>
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_play"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="70dp"
|
||||
a:layout_gravity="center"
|
||||
a:layout_weight="1"
|
||||
a:importantForAccessibility="no"
|
||||
a:src="@drawable/media_start"
|
||||
a:scaleType="fitCenter"/>
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/control_next"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="40dp"
|
||||
a:layout_gravity="center"
|
||||
a:layout_weight="0.6"
|
||||
a:importantForAccessibility="no"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/media_forward"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content">
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
a:id="@+id/select_album_art"
|
||||
@ -12,7 +12,7 @@
|
||||
a:layout_marginEnd="10dip"
|
||||
a:contentDescription="@null"
|
||||
a:scaleType="fitCenter"
|
||||
a:src="@drawable/unknown_album"/>
|
||||
a:src="@drawable/unknown_album" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/select_album_title"
|
||||
@ -20,10 +20,10 @@
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_toEndOf="@+id/select_album_art"
|
||||
a:ellipsize="end"
|
||||
a:paddingEnd="4dip"
|
||||
a:paddingTop="10dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium"/>
|
||||
a:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/select_album_artist"
|
||||
@ -34,7 +34,7 @@
|
||||
a:ellipsize="end"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
a:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/select_album_genre"
|
||||
@ -45,7 +45,7 @@
|
||||
a:ellipsize="end"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
a:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/select_album_year"
|
||||
@ -56,7 +56,7 @@
|
||||
a:ellipsize="end"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
a:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/select_album_song_count"
|
||||
@ -67,7 +67,7 @@
|
||||
a:ellipsize="none"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
a:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/select_album_duration"
|
||||
@ -78,6 +78,6 @@
|
||||
a:ellipsize="none"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
a:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
</RelativeLayout>
|
@ -11,9 +11,6 @@
|
||||
a:layout_height="wrap_content"
|
||||
a:gravity="center_vertical"
|
||||
a:paddingStart="6dp"
|
||||
a:textAllCaps="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"
|
||||
a:textColor="?attr/colorPrimary"
|
||||
a:textStyle="bold" />
|
||||
a:theme="@style/Ultrasonic.AllCapsLabel" />
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -98,12 +98,12 @@
|
||||
a:layout_marginTop="8dp"
|
||||
a:layout_marginEnd="10dip"
|
||||
a:indeterminate="true"
|
||||
app:indicatorColor="?attr/color_menu_selected"
|
||||
app:indicatorColor="?attr/colorOnSurface"
|
||||
app:indicatorSize="20dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/song_duration"
|
||||
app:layout_constraintEnd_toEndOf="@id/star_barrier"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:trackColor="?attr/color_selected" />
|
||||
app:trackColor="?attr/colorSurfaceVariant" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/song_duration"
|
||||
|
@ -11,15 +11,13 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/main_music"
|
||||
android:theme="@style/Ultrasonic.AllCapsLabel"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="6dp"
|
||||
android:text="@string/main.music"
|
||||
android:textAllCaps="true"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?attr/colorPrimary"
|
||||
android:textStyle="bold" />
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/main_artists_button"
|
||||
@ -61,10 +59,7 @@
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="6dp"
|
||||
android:text="@string/main.songs_title"
|
||||
android:textAllCaps="true"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?attr/colorPrimary"
|
||||
android:textStyle="bold" />
|
||||
android:theme="@style/Ultrasonic.AllCapsLabel" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/main_songs_button"
|
||||
@ -90,15 +85,12 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/main_albums"
|
||||
android:theme="@style/Ultrasonic.AllCapsLabel"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="6dp"
|
||||
android:text="@string/main.albums_title"
|
||||
android:textAllCaps="true"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?attr/colorPrimary"
|
||||
android:textStyle="bold" />
|
||||
android:text="@string/main.albums_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/main_albums_newest"
|
||||
@ -195,10 +187,7 @@
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="6dp"
|
||||
android:text="@string/main.videos"
|
||||
android:textAllCaps="true"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?attr/colorPrimary"
|
||||
android:textStyle="bold" />
|
||||
android:theme="@style/Ultrasonic.AllCapsLabel" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/main_videos"
|
||||
|
@ -19,7 +19,7 @@
|
||||
a:focusable="true"
|
||||
a:scaleType="fitCenter"
|
||||
a:contentDescription="@string/buttons.shuffle"
|
||||
app:icon="@drawable/media_shuffle_normal"
|
||||
app:icon="@drawable/media_shuffle"
|
||||
app:iconGravity="textTop" />
|
||||
|
||||
<org.moire.ultrasonic.view.AutoRepeatButton
|
||||
@ -33,7 +33,7 @@
|
||||
a:contentDescription="@string/buttons.previous"
|
||||
a:focusable="true"
|
||||
a:scaleType="fitCenter"
|
||||
app:icon="@drawable/media_backward_normal"
|
||||
app:icon="@drawable/media_backward"
|
||||
app:iconGravity="textTop"
|
||||
app:iconSize="32dp" />
|
||||
|
||||
@ -48,7 +48,7 @@
|
||||
a:scaleType="fitCenter"
|
||||
tools:visibility="gone"
|
||||
a:contentDescription="@string/buttons.play"
|
||||
app:icon="@drawable/media_start_normal"
|
||||
app:icon="@drawable/media_start"
|
||||
app:iconGravity="textTop"
|
||||
app:iconSize="48dp" />
|
||||
|
||||
@ -62,7 +62,7 @@
|
||||
a:contentDescription="@string/buttons.pause"
|
||||
a:focusable="true"
|
||||
a:scaleType="fitCenter"
|
||||
app:icon="@drawable/media_pause_normal"
|
||||
app:icon="@drawable/media_pause"
|
||||
app:iconGravity="textTop"
|
||||
app:iconSize="48dp" />
|
||||
|
||||
@ -77,7 +77,7 @@
|
||||
a:scaleType="fitCenter"
|
||||
tools:visibility="gone"
|
||||
a:contentDescription="@string/buttons.stop"
|
||||
app:icon="@drawable/media_stop_normal"
|
||||
app:icon="@drawable/media_stop"
|
||||
app:iconGravity="textTop"
|
||||
app:iconSize="48dp" />
|
||||
|
||||
@ -92,7 +92,7 @@
|
||||
a:contentDescription="@string/buttons.next"
|
||||
a:focusable="true"
|
||||
a:scaleType="fitCenter"
|
||||
app:icon="@drawable/media_forward_normal"
|
||||
app:icon="@drawable/media_forward"
|
||||
app:iconGravity="textTop"
|
||||
app:iconSize="32dp" />
|
||||
|
||||
|
@ -6,7 +6,8 @@
|
||||
a:id="@+id/drawer_layout"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="match_parent"
|
||||
tools:context="org.moire.ultrasonic.activity.NavigationActivity">
|
||||
tools:context="org.moire.ultrasonic.activity.NavigationActivity"
|
||||
a:fitsSystemWindows="true">
|
||||
|
||||
<RelativeLayout
|
||||
a:layout_width="match_parent"
|
||||
@ -44,7 +45,6 @@
|
||||
a:layout_height="match_parent"
|
||||
a:layout_gravity="start"
|
||||
a:fitsSystemWindows="true"
|
||||
a:background="?attr/color_menu_background"
|
||||
app:headerLayout="@layout/navigation_header"
|
||||
app:menu="@menu/navigation" />
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
@ -24,19 +24,20 @@
|
||||
style="@style/Widget.Material3.Button.TextButton.Icon"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginTop="0dp"
|
||||
a:layout_marginStart="3dp"
|
||||
a:layout_marginTop="24dp"
|
||||
a:background="@drawable/default_ripple"
|
||||
a:gravity="center_vertical"
|
||||
a:paddingHorizontal="22dp"
|
||||
a:paddingTop="16dp"
|
||||
a:paddingBottom="16dp"
|
||||
a:text="@string/main.offline"
|
||||
a:textAppearance="@style/MenuDrawer.Widget"
|
||||
a:textAppearance="@style/TextAppearance.Material3.TitleMedium"
|
||||
a:textColor="?attr/colorOnPrimary"
|
||||
a:textSize="17sp"
|
||||
a:textStyle="bold"
|
||||
a:textSize="18sp"
|
||||
app:icon="@drawable/ic_menu_select_server"
|
||||
app:iconPadding="12dp"
|
||||
app:iconSize="24dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
|
@ -6,16 +6,17 @@
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorSecondaryContainer"
|
||||
tools:ignore="overdraw">
|
||||
tools:ignore="Overdraw">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/now_playing_image"
|
||||
android:layout_width="72.0dip"
|
||||
android:layout_height="72.0dip"
|
||||
android:layout_marginStart="0dp"
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
android:importantForAccessibility="no" />
|
||||
android:id="@+id/now_playing_image"
|
||||
android:layout_width="72.0dip"
|
||||
android:layout_height="72.0dip"
|
||||
android:layout_marginStart="0dp"
|
||||
android:elevation="4dp"
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
android:importantForAccessibility="no" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0.0dp"
|
||||
@ -58,7 +59,7 @@
|
||||
android:contentDescription="@string/buttons.play"
|
||||
android:focusable="false"
|
||||
android:scaleType="fitCenter"
|
||||
app:icon="@drawable/media_pause_normal"
|
||||
app:icon="@drawable/media_pause"
|
||||
app:iconGravity="textTop"
|
||||
app:iconSize="42dp" />
|
||||
|
||||
|
@ -4,238 +4,252 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="match_parent"
|
||||
a:fillViewport="true">
|
||||
a:fillViewport="true"
|
||||
tools:ignore="HardcodedText">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
a:id="@+id/edit_server_name"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:hint="@string/settings.server_name"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
a:paddingStart="16dp"
|
||||
a:paddingEnd="16dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
a:id="@+id/edit_server_name"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:inputType="text"
|
||||
a:maxLines="1" />
|
||||
a:hint="@string/settings.server_name"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginBottom="8dp"
|
||||
a:inputType="text"
|
||||
a:text=" "
|
||||
a:maxLines="1" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
a:id="@+id/edit_server_address"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginBottom="20dp"
|
||||
a:hint="@string/settings.server_address"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_server_name">
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
a:id="@+id/edit_server_address"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:text="http://"
|
||||
a:inputType="textWebEmailAddress" />
|
||||
a:layout_marginBottom="20dp"
|
||||
a:hint="@string/settings.server_address"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_server_name">
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:inputType="textWebEmailAddress"
|
||||
a:text="http://" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/edit_server_color_text"
|
||||
style="@style/Widget.AppCompat.CompoundButton.Switch"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="5dp"
|
||||
a:layout_marginLeft="5dp"
|
||||
a:text="@string/settings.server_color"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/edit_server_color_picker"
|
||||
app:layout_constraintBottom_toBottomOf="@id/edit_server_color_picker"/>
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<ImageView
|
||||
a:id="@+id/edit_server_color_picker"
|
||||
a:layout_width="48dp"
|
||||
a:layout_height="32dp"
|
||||
a:layout_margin="8dp"
|
||||
a:src="@drawable/rounded_border"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_server_address"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/edit_authentication_header"
|
||||
style="@style/MenuDrawer.Widget.Category"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginTop="15dp"
|
||||
a:text="@string/server_editor.authentication"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_server_username"
|
||||
app:layout_constraintStart_toStartOf="@id/edit_server_username"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_server_color_picker" />
|
||||
<TextView
|
||||
a:id="@+id/edit_authentication_header"
|
||||
style="@style/Ultrasonic.AllCapsLabel.Inset"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginTop="15dp"
|
||||
a:layout_marginBottom="8dp"
|
||||
a:text="@string/server_editor.authentication"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_server_username"
|
||||
app:layout_constraintStart_toStartOf="@id/edit_server_username"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_server_address" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
a:id="@+id/edit_server_username"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:hint="@string/settings.server_username"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_server_password"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_authentication_header">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
a:id="@+id/edit_server_username"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:inputType="text"
|
||||
a:maxLines="1" />
|
||||
a:hint="@string/settings.server_username"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_server_password"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_authentication_header">
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginTop="8dp"
|
||||
a:layout_marginBottom="0dp"
|
||||
a:inputType="text"
|
||||
a:text=" "
|
||||
a:maxLines="1" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
a:id="@+id/edit_server_password"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginBottom="21dp"
|
||||
a:hint="@string/settings.server_password"
|
||||
app:endIconMode="password_toggle"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_advanced_header"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_server_username">
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
a:id="@+id/edit_server_password"
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:inputType="textPassword" />
|
||||
a:layout_marginBottom="21dp"
|
||||
a:hint="@string/settings.server_password"
|
||||
app:endIconMode="password_toggle"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_advanced_header"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_server_username">
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:inputType="textPassword"
|
||||
a:text=" "
|
||||
/>
|
||||
|
||||
<TextView
|
||||
a:id="@+id/edit_advanced_header"
|
||||
style="@style/MenuDrawer.Widget.Category"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginBottom="8dp"
|
||||
a:text="@string/server_editor.advanced"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_self_signed"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_server_password" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/edit_self_signed_title"
|
||||
style="@style/Widget.AppCompat.CompoundButton.Switch"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="5dp"
|
||||
a:text="@string/settings.title.allow_self_signed_certificate"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_ldap_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_advanced_header" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
a:id="@+id/edit_self_signed"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="8dp"
|
||||
a:layout_marginEnd="5dp"
|
||||
a:layout_marginBottom="8dp"
|
||||
a:checked="false"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_ldap_title"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/edit_self_signed_title"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_advanced_header" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/edit_ldap_title"
|
||||
style="@style/Widget.AppCompat.CompoundButton.Switch"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="5dp"
|
||||
a:text="@string/settings.title.force_plain_text_password"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_ldap_description"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_self_signed" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/edit_ldap_description"
|
||||
style="@style/TextAppearance.AppCompat.Small"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="5dp"
|
||||
a:text="@string/settings.summary.force_plain_text_password"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_jukebox"
|
||||
app:layout_constraintEnd_toStartOf="@id/edit_ldap"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_ldap_title" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
a:id="@+id/edit_ldap"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginEnd="5dp"
|
||||
a:layout_marginStart="8dp"
|
||||
a:checked="false"
|
||||
app:layout_constraintBottom_toBottomOf="@id/edit_ldap_description"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/edit_ldap_description"
|
||||
app:layout_constraintTop_toTopOf="@id/edit_ldap_title" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/edit_jukebox_title"
|
||||
style="@style/Widget.AppCompat.CompoundButton.Switch"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="5dp"
|
||||
a:layout_marginTop="8dp"
|
||||
a:text="@string/jukebox.is_default"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_ldap_description" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
a:id="@+id/edit_jukebox"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="8dp"
|
||||
a:layout_marginTop="8dp"
|
||||
a:layout_marginEnd="5dp"
|
||||
a:checked="false"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/edit_jukebox_title"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_ldap_description" />
|
||||
|
||||
<Button
|
||||
a:id="@+id/edit_test"
|
||||
style="?attr/materialButtonOutlinedStyle"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginTop="8dp"
|
||||
a:layout_marginStart="5dp"
|
||||
a:layout_marginEnd="2dp"
|
||||
a:text="@string/settings.test_connection_title"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/edit_save"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_jukebox"
|
||||
app:layout_constraintVertical_bias="1.0" />
|
||||
|
||||
<Button
|
||||
a:id="@+id/edit_save"
|
||||
style="?attr/materialButtonOutlinedStyle"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="0dp"
|
||||
a:layout_marginStart="2dp"
|
||||
a:layout_marginEnd="5dp"
|
||||
a:text="@string/common.save"
|
||||
app:layout_constraintBottom_toBottomOf="@id/edit_test"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/edit_test"
|
||||
app:layout_constraintTop_toTopOf="@id/edit_test" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<TextView
|
||||
a:id="@+id/edit_advanced_header"
|
||||
style="@style/Ultrasonic.AllCapsLabel.Inset"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginBottom="8dp"
|
||||
a:text="@string/server_editor.advanced"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_server_color_text"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_server_password" />
|
||||
|
||||
|
||||
<ImageView
|
||||
a:id="@+id/edit_server_color_picker"
|
||||
a:layout_width="48dp"
|
||||
a:layout_height="32dp"
|
||||
a:layout_margin="8dp"
|
||||
a:src="@drawable/rounded_border"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_advanced_header"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/edit_server_color_text"
|
||||
style="@style/Widget.AppCompat.CompoundButton.Switch"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="5dp"
|
||||
a:layout_marginLeft="5dp"
|
||||
a:text="@string/settings.server_color"
|
||||
app:layout_constraintBottom_toBottomOf="@id/edit_server_color_picker"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/edit_server_color_picker" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/edit_self_signed_title"
|
||||
style="@style/Widget.AppCompat.CompoundButton.Switch"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="5dp"
|
||||
a:text="@string/settings.title.allow_self_signed_certificate"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_plaintext_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_server_color_text" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
a:id="@+id/edit_self_signed"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="8dp"
|
||||
a:layout_marginEnd="5dp"
|
||||
a:layout_marginBottom="8dp"
|
||||
a:checked="false"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_plaintext_title"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/edit_self_signed_title"
|
||||
app:layout_constraintTop_toBottomOf="@+id/edit_server_color_text" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/edit_plaintext_title"
|
||||
style="@style/Widget.AppCompat.CompoundButton.Switch"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="5dp"
|
||||
a:text="@string/settings.title.force_plain_text_password"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_plaintext_description"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_self_signed" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/edit_plaintext_description"
|
||||
style="@style/TextAppearance.AppCompat.Small"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="5dp"
|
||||
a:text="@string/settings.summary.force_plain_text_password"
|
||||
app:layout_constraintBottom_toTopOf="@id/edit_jukebox"
|
||||
app:layout_constraintEnd_toStartOf="@id/edit_plaintext"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_plaintext_title" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
a:id="@+id/edit_plaintext"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="8dp"
|
||||
a:layout_marginEnd="5dp"
|
||||
a:checked="false"
|
||||
app:layout_constraintBottom_toBottomOf="@id/edit_plaintext_description"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/edit_plaintext_description"
|
||||
app:layout_constraintTop_toTopOf="@id/edit_plaintext_title" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/edit_jukebox_title"
|
||||
style="@style/Widget.AppCompat.CompoundButton.Switch"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="5dp"
|
||||
a:layout_marginTop="8dp"
|
||||
a:text="@string/jukebox.is_default"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_plaintext_description" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
a:id="@+id/edit_jukebox"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="8dp"
|
||||
a:layout_marginTop="8dp"
|
||||
a:layout_marginEnd="5dp"
|
||||
a:checked="false"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/edit_jukebox_title"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_plaintext_description" />
|
||||
|
||||
<Button
|
||||
a:id="@+id/edit_test"
|
||||
style="?attr/materialButtonOutlinedStyle"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginStart="5dp"
|
||||
a:layout_marginTop="8dp"
|
||||
a:layout_marginEnd="2dp"
|
||||
a:text="@string/settings.test_connection_title"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/edit_save"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/edit_jukebox"
|
||||
app:layout_constraintVertical_bias="1.0" />
|
||||
|
||||
<Button
|
||||
a:id="@+id/edit_save"
|
||||
style="?attr/materialButtonOutlinedStyle"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="0dp"
|
||||
a:layout_marginStart="2dp"
|
||||
a:layout_marginEnd="5dp"
|
||||
a:text="@string/common.save"
|
||||
app:layout_constraintBottom_toBottomOf="@id/edit_test"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/edit_test"
|
||||
app:layout_constraintTop_toTopOf="@id/edit_test" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</ScrollView>
|
@ -22,8 +22,7 @@
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:text="@string/share_comment"
|
||||
a:textAllCaps="true"
|
||||
a:textColor="?attr/colorPrimary"
|
||||
a:theme="@style/Ultrasonic.AllCapsLabel"
|
||||
a:id="@+id/textViewComment"
|
||||
a:layout_gravity="center_horizontal"/>
|
||||
|
||||
@ -40,8 +39,7 @@
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:text="@string/settings.share_expiration"
|
||||
a:textAllCaps="true"
|
||||
a:textColor="?attr/colorPrimary"
|
||||
a:theme="@style/Ultrasonic.AllCapsLabel"
|
||||
a:id="@+id/textViewExpiration"
|
||||
a:layout_gravity="center_horizontal"/>
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:a="http://schemas.android.com/apk/res/android">
|
||||
<menu xmlns:a="http://schemas.android.com/apk/res/android">
|
||||
<group
|
||||
a:checkableBehavior="none"
|
||||
a:enabled="true"
|
||||
@ -48,7 +47,7 @@
|
||||
<item
|
||||
a:id="@+id/playerFragment"
|
||||
a:checkable="true"
|
||||
a:icon="@drawable/media_start_normal"
|
||||
a:icon="@drawable/media_start"
|
||||
a:title="@string/button_bar.now_playing" />
|
||||
<item
|
||||
a:id="@+id/podcastFragment"
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
<item
|
||||
a:id="@+id/menu_item_toggle_list"
|
||||
a:icon="@drawable/media_toggle_list_normal"
|
||||
a:icon="@drawable/media_toggle_list"
|
||||
app:showAsAction="always"
|
||||
a:title="@string/download.toggle_playlist"/>
|
||||
<item
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
<item
|
||||
a:id="@+id/select_album_play_all"
|
||||
a:icon="@drawable/media_start_normal"
|
||||
a:icon="@drawable/media_start"
|
||||
app:showAsAction="ifRoom|withText"
|
||||
a:title="@string/select_album.play_all"/>
|
||||
|
||||
|
8
ultrasonic/src/main/res/values-night/themes.xml
Normal file
8
ultrasonic/src/main/res/values-night/themes.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="UltrasonicTheme.DayNight" parent="Theme.Material3.DynamicColors.DayNight">
|
||||
<item name="colorPrimaryDark">?attr/colorSurface</item>
|
||||
<item name="colorControlNormal">?attr/colorOnSurface</item>
|
||||
<item name="colorControlHighlight">?attr/colorSecondary</item>
|
||||
</style>
|
||||
</resources>
|
14
ultrasonic/src/main/res/values-v31/styles.xml
Normal file
14
ultrasonic/src/main/res/values-v31/styles.xml
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!--
|
||||
Having clipToOutline to true is needed for the background (that has id with
|
||||
android:id/background so that the system knows the widget has been updated
|
||||
and doesn't need to be clipped by the launcher.
|
||||
-->
|
||||
<style name="Widget.AppWidget.AppWidget.Container" parent="android:Widget">
|
||||
<item name="android:id">@android:id/background</item>
|
||||
<item name="android:padding">?attr/appWidgetPadding</item>
|
||||
<item name="android:background">@drawable/app_widget_background</item>
|
||||
<item name="android:clipToOutline">true</item>
|
||||
</style>
|
||||
</resources>
|
17
ultrasonic/src/main/res/values-v31/themes.xml
Normal file
17
ultrasonic/src/main/res/values-v31/themes.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!--
|
||||
Having themes.xml for v31 variant because @android:dimen/system_app_widget_background_radius
|
||||
and @android:dimen/system_app_widget_inner_radius requires API level 31.
|
||||
-->
|
||||
<style name="Theme.AppWidget.AppWidgetContainer" parent="Theme.AppWidget.AppWidgetContainerParent">
|
||||
<item name="appWidgetRadius">@android:dimen/system_app_widget_background_radius</item>
|
||||
<item name="appWidgetInnerRadius">@android:dimen/system_app_widget_inner_radius</item>
|
||||
<item name="appWidgetPadding">16dp</item>
|
||||
<item name="android:imageButtonStyle">@style/Theme.AppWidget.ImageButton</item>
|
||||
</style>
|
||||
<style name="Theme.AppWidget.AppWidgetContainerCropped" parent="Theme.AppWidget.AppWidgetContainer">
|
||||
<!-- Apply padding to avoid the content of the widget colliding with the rounded corners -->
|
||||
<item name="appWidgetPadding">0dp</item>
|
||||
</style>
|
||||
</resources>
|
@ -2,11 +2,13 @@
|
||||
<resources>
|
||||
|
||||
<string-array name="themeValues" translatable="false">
|
||||
<item>@string/preferences_key_theme_light</item>
|
||||
<item>@string/preferences_key_theme_dark</item>
|
||||
<item>@string/preferences_key_theme_black</item>
|
||||
<item>@string/setting_key.theme_day_night</item>
|
||||
<item>@string/setting_key.theme_light</item>
|
||||
<item>@string/setting_key.theme_dark</item>
|
||||
<item>@string/setting_key.theme_black</item>
|
||||
</string-array>
|
||||
<string-array name="themeNames" translatable="false">
|
||||
<item>@string/settings.theme_day_night</item>
|
||||
<item>@string/settings.theme_light</item>
|
||||
<item>@string/settings.theme_dark</item>
|
||||
<item>@string/settings.theme_black</item>
|
||||
|
8
ultrasonic/src/main/res/values/attrs.xml
Normal file
8
ultrasonic/src/main/res/values/attrs.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<resources>
|
||||
<declare-styleable name="AppWidgetAttrs">
|
||||
<attr name="appWidgetPadding" format="dimension" />
|
||||
<attr name="appWidgetInnerRadius" format="dimension" />
|
||||
<attr name="appWidgetRadius" format="dimension" />
|
||||
<attr name="appWidgetBackground" format="color" />
|
||||
</declare-styleable>
|
||||
</resources>
|
@ -1,7 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="appwidget_text">#FFFFFF</color>
|
||||
<color name="appwidget_button_background">#00000000</color>
|
||||
<color name="background_color_black">#000000</color>
|
||||
<color name="selected_menu_dark">#F3F3F3</color>
|
||||
<color name="selected_menu_light">#000000</color>
|
||||
|
@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!--
|
||||
Do not forget to match string resources with constants
|
||||
-->
|
||||
<string translatable="false" name="preferences_key_theme_light">light</string>
|
||||
<string translatable="false" name="preferences_key_theme_dark">dark</string>
|
||||
<string translatable="false" name="preferences_key_theme_black">black</string>
|
||||
|
||||
</resources>
|
@ -6,6 +6,7 @@
|
||||
<string name="setting_key.theme_light" translatable="false">light</string>
|
||||
<string name="setting_key.theme_dark" translatable="false">dark</string>
|
||||
<string name="setting_key.theme_black" translatable="false">black</string>
|
||||
<string name="setting_key.theme_day_night" translatable="false">dayNight</string>
|
||||
<string name="setting_key.display_bitrate_with_artist" translatable="false">displayBitrateWithArtist</string>
|
||||
<string name="setting_key.use_folder_for_album_artist" translatable="false">useFolderForAlbumArtist</string>
|
||||
<string name="setting_key.show_track_number" translatable="false">showTrackNumber</string>
|
||||
|
@ -302,6 +302,7 @@
|
||||
<string name="settings.test_connection_title">Test Connection</string>
|
||||
<string name="settings.testing_ok">Connection is OK</string>
|
||||
<string name="settings.testing_unlicensed">Connection is OK. Server unlicensed.</string>
|
||||
<string name="settings.theme_day_night">Day & Night</string>
|
||||
<string name="settings.theme_light">Light</string>
|
||||
<string name="settings.theme_dark">Dark</string>
|
||||
<string name="settings.theme_black">Black</string>
|
||||
|
@ -1,20 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="MenuDrawer"/>
|
||||
|
||||
<style name="MenuDrawer.Widget"/>
|
||||
|
||||
<style name="MenuDrawer.Widget.Category">
|
||||
<style name="Ultrasonic.AllCapsLabel" parent="">
|
||||
<item name="android:textStyle">bold</item>
|
||||
<item name="android:textColor">?attr/colorPrimary</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
|
||||
<item name="android:textAllCaps">true</item>
|
||||
<item name="android:gravity">center_vertical</item>
|
||||
<item name="android:paddingStart">16dp</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
<item name="android:ellipsize">end</item>
|
||||
</style>
|
||||
|
||||
<style name="Ultrasonic.AllCapsLabel.Inset" parent="Ultrasonic.AllCapsLabel">
|
||||
<item name="android:paddingStart">16dp</item>
|
||||
</style>
|
||||
|
||||
<style name="roundedImageView" parent="">
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">8dp</item>
|
||||
@ -25,9 +25,44 @@
|
||||
<item name="cornerSize">2dp</item>
|
||||
</style>
|
||||
|
||||
<attr name="color_background" format="reference"/>
|
||||
<attr name="color_selected" format="reference"/>
|
||||
<attr name="color_menu_background" format="reference"/>
|
||||
<attr name="color_menu_selected" format="reference"/>
|
||||
<style name="Widget.AppWidget.AppWidget.Container" parent="android:Widget">
|
||||
<item name="android:id">@android:id/background</item>
|
||||
<item name="android:padding">?attr/appWidgetPadding</item>
|
||||
<item name="android:background">@drawable/app_widget_background</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.AppWidget.AppWidgetContainerParent" parent="Theme.Material3.DynamicColors.DayNight">
|
||||
<!-- Radius of the outer bound of widgets to make the rounded corners -->
|
||||
<item name="appWidgetRadius">4dp</item>
|
||||
<item name="appWidgetBackground">?attr/colorSurfaceVariant</item>
|
||||
<item name="colorControlNormal">?attr/colorOnPrimary</item>
|
||||
<item name="android:colorButtonNormal">?attr/colorPrimary</item>
|
||||
|
||||
<!--
|
||||
Radius of the inner view's bound of widgets to make the rounded corners.
|
||||
It needs to be 8dp or less than the value of appWidgetRadius
|
||||
-->
|
||||
<item name="appWidgetInnerRadius">8dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.AppWidget.AppWidgetContainer" parent="Theme.AppWidget.AppWidgetContainerParent">
|
||||
<item name="appWidgetRadius">0dp</item>
|
||||
<item name="appWidgetInnerRadius">0dp</item>
|
||||
<!-- Apply padding to avoid the content of the widget colliding with the rounded corners -->
|
||||
<item name="appWidgetPadding">4dp</item>
|
||||
<item name="android:imageButtonStyle">@style/Theme.AppWidget.ImageButton</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.AppWidget.ImageButton" parent="Widget.AppCompat.ImageButton">
|
||||
<item name="android:tint">?attr/colorPrimary</item>
|
||||
<item name="android:background">@null</item>
|
||||
<item name="android:scaleType">fitXY</item>
|
||||
<item name="android:adjustViewBounds">true</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.AppWidget.AppWidgetContainerCropped" parent="Theme.AppWidget.AppWidgetContainer">
|
||||
<!-- Apply padding to avoid the content of the widget colliding with the rounded corners -->
|
||||
<item name="appWidgetPadding">4dp</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
|
@ -1,41 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<style name="CleanSearchStyle" parent="Widget.AppCompat.SearchView">
|
||||
<item name="queryBackground">@null</item>
|
||||
<item name="submitBackground">@null</item>
|
||||
</style>
|
||||
|
||||
<style name="UltrasonicTheme.Black" parent="Theme.Material3.Dark">
|
||||
<!-- Here we define some basic attributes that are the same for each theme -->
|
||||
<style name="UltrasonicTheme.Base" parent="">
|
||||
<item name="searchViewStyle">@style/CleanSearchStyle</item>
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
<!-- The day & night theme. There is a night specific override in the values-night folder -->
|
||||
<style name="UltrasonicTheme.DayNight" parent="Theme.Material3.DynamicColors.DayNight">
|
||||
<item name="colorControlNormal">?attr/colorOnSurface</item>
|
||||
<item name="colorControlHighlight">?attr/colorSecondary</item>
|
||||
</style>
|
||||
|
||||
<style name="UltrasonicTheme.Black" parent="Theme.Material3.Dark">
|
||||
<item name="colorPrimaryDark">?attr/backgroundColor</item>
|
||||
<item name="android:colorBackground">@color/background_color_black</item>
|
||||
<item name="color_background">?attr/colorSurface</item>
|
||||
<item name="color_selected">?attr/colorPrimaryContainer</item>
|
||||
<item name="color_menu_background">?attr/colorSurface</item>
|
||||
<item name="color_menu_selected">?attr/colorOnSurface</item>
|
||||
<item name="colorControlNormal">?attr/colorOnSurface</item>
|
||||
<item name="searchViewStyle">@style/CleanSearchStyle</item>
|
||||
</style>
|
||||
|
||||
<style name="UltrasonicTheme.Dark" parent="Theme.Material3.DynamicColors.Dark">
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="colorPrimaryDark">?attr/backgroundColor</item>
|
||||
<item name="color_background">?attr/colorSurface</item>
|
||||
<item name="color_selected">?attr/colorPrimaryContainer</item>
|
||||
<item name="color_menu_background">?attr/colorSurface</item>
|
||||
<item name="color_menu_selected">?attr/colorOnSurface</item>
|
||||
<item name="colorPrimaryDark">?attr/colorSurface</item>
|
||||
<item name="colorControlNormal">?attr/colorOnSurface</item>
|
||||
<item name="searchViewStyle">@style/CleanSearchStyle</item>
|
||||
<item name="colorControlHighlight">?attr/colorSecondary</item>
|
||||
</style>
|
||||
|
||||
<style name="UltrasonicTheme.Light" parent="Theme.Material3.DynamicColors.Light">
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="color_background">?attr/colorSurface</item>
|
||||
<item name="color_selected">?attr/colorPrimaryContainer</item>
|
||||
<item name="color_menu_background">?attr/colorSurface</item>
|
||||
<item name="color_menu_selected">?attr/colorOnSurface</item>
|
||||
<item name="colorControlNormal">?attr/colorOnSurface</item>
|
||||
<item name="searchViewStyle">@style/CleanSearchStyle</item>
|
||||
<item name="colorControlHighlight">?attr/colorSecondary</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
17
ultrasonic/src/main/res/xml/appwidget_info.xml
Normal file
17
ultrasonic/src/main/res/xml/appwidget_info.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<appwidget-provider xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
a:minWidth="220dp"
|
||||
a:minHeight="50dp"
|
||||
a:targetCellWidth="4"
|
||||
a:targetCellHeight="1"
|
||||
a:minResizeWidth="220dp"
|
||||
a:minResizeHeight="50dp"
|
||||
a:maxResizeWidth="600dp"
|
||||
a:maxResizeHeight="600dp"
|
||||
a:updatePeriodMillis="86400000"
|
||||
a:resizeMode="horizontal|vertical"
|
||||
a:previewImage="@drawable/widget_preview"
|
||||
a:widgetCategory="home_screen|keyguard"
|
||||
a:initialLayout="@layout/appwidget_landscape_small"
|
||||
tools:ignore="UnusedAttribute" />
|
@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<appwidget-provider xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
a:minWidth="250dp"
|
||||
a:minHeight="40dp"
|
||||
a:updatePeriodMillis="0"
|
||||
a:resizeMode="none"
|
||||
a:previewImage="@drawable/preview4x1"
|
||||
a:widgetCategory="home_screen|keyguard"
|
||||
a:initialLayout="@layout/appwidget4x1"
|
||||
tools:ignore="UnusedAttribute" />
|
@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<appwidget-provider xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
a:minWidth="250dp"
|
||||
a:minHeight="110dp"
|
||||
a:updatePeriodMillis="0"
|
||||
a:resizeMode="none"
|
||||
a:previewImage="@drawable/preview4x2"
|
||||
a:widgetCategory="home_screen|keyguard"
|
||||
a:initialLayout="@layout/appwidget4x2"
|
||||
tools:ignore="UnusedAttribute" />
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<appwidget-provider xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
a:minWidth="250dp"
|
||||
a:minHeight="180dp"
|
||||
a:updatePeriodMillis="0"
|
||||
a:resizeMode="none"
|
||||
a:previewImage="@drawable/preview4x3"
|
||||
a:widgetCategory="home_screen|keyguard"
|
||||
a:initialLayout="@layout/appwidget4x3"/>
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<appwidget-provider xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
a:minWidth="250dp"
|
||||
a:minHeight="250dp"
|
||||
a:updatePeriodMillis="0"
|
||||
a:resizeMode="none"
|
||||
a:previewImage="@drawable/preview4x3"
|
||||
a:widgetCategory="home_screen|keyguard"
|
||||
a:initialLayout="@layout/appwidget4x4" />
|
@ -8,7 +8,7 @@
|
||||
a:title="@string/settings.appearance_title"
|
||||
app:iconSpaceReserved="false">
|
||||
<ListPreference
|
||||
a:defaultValue="@string/preferences_key_theme_dark"
|
||||
a:defaultValue="@string/setting_key.theme_day_night"
|
||||
a:entries="@array/themeNames"
|
||||
a:entryValues="@array/themeValues"
|
||||
a:key="@string/setting_key.theme"
|
||||
|
Loading…
x
Reference in New Issue
Block a user