Private
Public Access
Minamp 1.6: adjustable UI size, larger text and controls
- New setting "Text and button size" (Normal / Large / Extra large): scales text, icons and buttons on top of the phone's density (App.UI_SCALES) - Larger default text, rows, tiles, touch targets and player icons; all sizes now live in res/values/dimens.xml - Seek bar knob drawn in code, since Android 2.x caches XML shapes at the size they were first loaded - Full-width buttons wrap to two lines instead of cutting words off - Shorter labels so they fit 240x320 screens in both languages - tools/check_fit.py checks that UI texts fit their slots at every size and language using Droid Sans metrics; build.sh runs it and setup_toolchain.sh fetches the font Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
fa67e95fde
commit
bbdab09f83
32 files changed
+457
-190
No files matched your search
@@ -2,3 +2,4 @@ build/
|
||||
toolchain/
|
||||
.DS_Store
|
||||
._*
|
||||
__pycache__/
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.minamp"
|
||||
android:versionCode="6"
|
||||
android:versionName="1.5"
|
||||
android:versionCode="7"
|
||||
android:versionName="1.6"
|
||||
android:installLocation="auto">
|
||||
|
||||
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="10" />
|
||||
|
||||
@@ -22,6 +22,13 @@ javac -nowarn -Xlint:-options -source 8 -target 8 -encoding UTF-8 -g:source,line
|
||||
-d $OUT/classes @$OUT/sources.txt 2>&1 | grep -v -E '^Picked up|^Note:' || true
|
||||
test -f $OUT/classes/com/minamp/HomeActivity.class
|
||||
|
||||
echo "== text fit check (240x320, all languages and sizes)"
|
||||
if [ -f "$T/fonts/droidsans-regular.ttf" ]; then
|
||||
python3 tools/check_fit.py "$T/fonts" || { echo "Some texts don't fit their space (see above)"; exit 1; }
|
||||
else
|
||||
echo "(skipped: run tools/setup_toolchain.sh to fetch the Droid Sans font)"
|
||||
fi
|
||||
|
||||
echo "== Dalvik 2.x link check"
|
||||
python3 tools/scan_dalvik.py $OUT/classes $ANDROID_JAR > $OUT/dalvik-scan.txt
|
||||
if ! grep -q "^total patterns: 0$" $OUT/dalvik-scan.txt; then
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@android:id/background"><shape><solid android:color="#40FFFFFF" /><corners android:radius="2dp" /><size android:height="4dp" /></shape></item>
|
||||
<item android:id="@android:id/background"><shape><solid android:color="#40FFFFFF" /><corners android:radius="3dp" /><size android:height="@dimen/seek_track" /></shape></item>
|
||||
<item android:id="@android:id/secondaryProgress"><clip><shape><solid android:color="#40FFFFFF" /><corners android:radius="2dp" /></shape></clip></item>
|
||||
<item android:id="@android:id/progress"><clip><shape><solid android:color="@color/text" /><corners android:radius="2dp" /></shape></clip></item>
|
||||
</layer-list>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
|
||||
<solid android:color="@color/text" />
|
||||
<size android:width="14dp" android:height="14dp" />
|
||||
<size android:width="@dimen/seek_thumb" android:height="@dimen/seek_thumb" />
|
||||
</shape>
|
||||
@@ -9,7 +9,7 @@
|
||||
<LinearLayout
|
||||
android:id="@+id/tabs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="32dp"
|
||||
android:layout_height="@dimen/tabs"
|
||||
android:orientation="horizontal">
|
||||
<TextView android:id="@+id/tab_home" style="@style/Tab" android:text="@string/tab_home" />
|
||||
<TextView android:id="@+id/tab_artists" style="@style/Tab" android:text="@string/tab_artists" />
|
||||
@@ -20,7 +20,7 @@
|
||||
<View
|
||||
android:id="@+id/tab_line"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="2dp"
|
||||
android:layout_height="3dp"
|
||||
android:background="@color/accent" />
|
||||
|
||||
<FrameLayout
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="44dp"
|
||||
android:layout_height="@dimen/np_topbar"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingLeft="2dp"
|
||||
@@ -17,11 +17,11 @@
|
||||
android:layout_width="0dp" android:layout_height="wrap_content"
|
||||
android:layout_weight="1" android:orientation="vertical" android:gravity="center">
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="@string/playing_from" android:textSize="9sp" android:textStyle="bold"
|
||||
android:textColor="@color/text2" />
|
||||
android:text="@string/playing_from" android:textSize="@dimen/text_tiny" android:textStyle="bold"
|
||||
android:textColor="@color/text2" android:singleLine="true" />
|
||||
<TextView android:id="@+id/np_from" style="@style/Sub"
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:textColor="@color/text" android:textSize="12sp" />
|
||||
android:textColor="@color/text" android:textSize="@dimen/text_sub" />
|
||||
</LinearLayout>
|
||||
<ImageButton android:id="@+id/np_queue" style="@style/IconButton" />
|
||||
</LinearLayout>
|
||||
@@ -33,8 +33,8 @@
|
||||
android:layout_weight="1"
|
||||
android:paddingLeft="20dp"
|
||||
android:paddingRight="20dp"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="6dp">
|
||||
android:paddingTop="2dp"
|
||||
android:paddingBottom="4dp">
|
||||
<com.minamp.SquareImageView
|
||||
android:id="@+id/np_art"
|
||||
android:layout_width="match_parent"
|
||||
@@ -48,17 +48,17 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingLeft="18dp"
|
||||
android:paddingRight="8dp">
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="4dp">
|
||||
<LinearLayout
|
||||
android:layout_width="0dp" android:layout_height="wrap_content"
|
||||
android:layout_weight="1" android:orientation="vertical">
|
||||
<TextView android:id="@+id/np_title" style="@style/Title"
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="@dimen/text_np_title" />
|
||||
<TextView android:id="@+id/np_sub" style="@style/Sub"
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:textSize="13sp" android:textColor="#CCFFFFFF" />
|
||||
android:textSize="@dimen/text_np_sub" android:textColor="#CCFFFFFF" />
|
||||
</LinearLayout>
|
||||
<ImageButton android:id="@+id/np_love" style="@style/IconButton" />
|
||||
</LinearLayout>
|
||||
@@ -68,13 +68,13 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:max="1000"
|
||||
android:paddingLeft="18dp"
|
||||
android:paddingRight="18dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="4dp"
|
||||
android:thumbOffset="7dp"
|
||||
android:maxHeight="4dp"
|
||||
android:minHeight="4dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="6dp"
|
||||
android:paddingBottom="2dp"
|
||||
android:thumbOffset="10dp"
|
||||
android:maxHeight="@dimen/seek_track"
|
||||
android:minHeight="@dimen/seek_track"
|
||||
android:progressDrawable="@drawable/seek_progress"
|
||||
android:thumb="@drawable/seek_thumb" />
|
||||
|
||||
@@ -82,64 +82,70 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="18dp"
|
||||
android:paddingRight="18dp">
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp">
|
||||
<TextView android:id="@+id/np_elapsed"
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:textSize="10sp" android:textColor="#B3FFFFFF" />
|
||||
android:textSize="@dimen/text_tiny" android:textColor="#CCFFFFFF" />
|
||||
<TextView android:id="@+id/np_status"
|
||||
android:layout_width="0dp" android:layout_height="wrap_content"
|
||||
android:layout_weight="1" android:gravity="center"
|
||||
android:textSize="10sp" android:textColor="#B3FFFFFF"
|
||||
android:textSize="@dimen/text_tiny" android:textColor="#CCFFFFFF"
|
||||
android:singleLine="true" android:ellipsize="end"
|
||||
android:paddingLeft="4dp" android:paddingRight="4dp" />
|
||||
<TextView android:id="@+id/np_remaining"
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:textSize="10sp" android:textColor="#B3FFFFFF" />
|
||||
android:textSize="@dimen/text_tiny" android:textColor="#CCFFFFFF" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- five equal cells: never wider than the screen, whatever the UI size -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="6dp"
|
||||
android:paddingRight="6dp">
|
||||
<ImageButton android:id="@+id/np_shuffle" style="@style/IconButton" />
|
||||
<View android:layout_width="0dp" android:layout_height="1dp" android:layout_weight="1" />
|
||||
<ImageButton android:id="@+id/np_prev" style="@style/IconButton" android:layout_width="50dp" android:layout_height="50dp" />
|
||||
<ImageButton android:id="@+id/np_play"
|
||||
android:layout_width="58dp" android:layout_height="58dp"
|
||||
android:layout_marginLeft="8dp" android:layout_marginRight="8dp"
|
||||
android:background="@drawable/bg_play_circle" android:scaleType="center" />
|
||||
<ImageButton android:id="@+id/np_next" style="@style/IconButton" android:layout_width="50dp" android:layout_height="50dp" />
|
||||
<View android:layout_width="0dp" android:layout_height="1dp" android:layout_weight="1" />
|
||||
<ImageButton android:id="@+id/np_repeat" style="@style/IconButton" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="36dp"
|
||||
android:layout_height="@dimen/np_controls"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingRight="12dp"
|
||||
android:layout_marginBottom="4dp">
|
||||
android:paddingLeft="4dp"
|
||||
android:paddingRight="4dp">
|
||||
<ImageButton android:id="@+id/np_shuffle" style="@style/IconButton"
|
||||
android:layout_width="0dp" android:layout_weight="1" />
|
||||
<ImageButton android:id="@+id/np_prev" style="@style/IconButton"
|
||||
android:layout_width="0dp" android:layout_weight="1" android:layout_height="@dimen/np_play" />
|
||||
<FrameLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1.3">
|
||||
<ImageButton android:id="@+id/np_play"
|
||||
android:layout_width="@dimen/np_play" android:layout_height="@dimen/np_play"
|
||||
android:layout_gravity="center"
|
||||
android:background="@drawable/bg_play_circle" android:scaleType="center" />
|
||||
</FrameLayout>
|
||||
<ImageButton android:id="@+id/np_next" style="@style/IconButton"
|
||||
android:layout_width="0dp" android:layout_weight="1" android:layout_height="@dimen/np_play" />
|
||||
<ImageButton android:id="@+id/np_repeat" style="@style/IconButton"
|
||||
android:layout_width="0dp" android:layout_weight="1" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/np_bottom"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
android:layout_marginBottom="2dp">
|
||||
<LinearLayout android:id="@+id/np_sleep"
|
||||
android:layout_width="wrap_content" android:layout_height="match_parent"
|
||||
android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent"
|
||||
android:orientation="horizontal" android:gravity="center_vertical"
|
||||
android:background="@drawable/bg_pressable" android:paddingLeft="6dp" android:paddingRight="8dp">
|
||||
<ImageView android:id="@+id/np_sleep_icon" android:layout_width="20dp" android:layout_height="20dp" />
|
||||
android:background="@drawable/bg_pressable" android:paddingLeft="8dp" android:paddingRight="8dp">
|
||||
<ImageView android:id="@+id/np_sleep_icon"
|
||||
android:layout_width="@dimen/np_small_icon" android:layout_height="@dimen/np_small_icon" />
|
||||
<TextView android:id="@+id/np_sleep_text"
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:textSize="11sp" android:textColor="#B3FFFFFF" android:paddingLeft="5dp"
|
||||
android:textSize="@dimen/text_np_small" android:textColor="#CCFFFFFF" android:paddingLeft="6dp"
|
||||
android:singleLine="true" android:ellipsize="end"
|
||||
android:text="@string/sleep" />
|
||||
</LinearLayout>
|
||||
<View android:layout_width="0dp" android:layout_height="1dp" android:layout_weight="1" />
|
||||
<TextView android:id="@+id/np_artist_link"
|
||||
android:layout_width="wrap_content" android:layout_height="match_parent"
|
||||
android:gravity="center_vertical" android:background="@drawable/bg_pressable"
|
||||
android:paddingLeft="8dp" android:paddingRight="8dp"
|
||||
android:textSize="11sp" android:textColor="#B3FFFFFF" android:text="@string/album_link" />
|
||||
android:paddingLeft="8dp" android:paddingRight="8dp" android:singleLine="true"
|
||||
android:textSize="@dimen/text_np_small" android:textColor="#CCFFFFFF" android:text="@string/album_link" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -5,7 +5,7 @@
|
||||
android:orientation="vertical">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:layout_height="@dimen/topbar"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingLeft="4dp"
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
android:text="@string/app_name" android:textSize="26sp" android:textStyle="bold"
|
||||
android:paddingTop="8dp" />
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:gravity="center" android:textColor="@color/text2" android:textSize="13sp"
|
||||
android:gravity="center" android:textColor="@color/text2" android:textSize="@dimen/text_sub"
|
||||
android:paddingTop="4dp" android:paddingBottom="22dp"
|
||||
android:text="@string/tagline" />
|
||||
<Button android:id="@+id/btn_signin" style="@style/ButtonAccent"
|
||||
@@ -34,7 +34,7 @@
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:layout_marginTop="18dp" android:padding="8dp"
|
||||
android:background="@drawable/bg_pressable"
|
||||
android:textColor="@color/text2" android:textSize="12sp"
|
||||
android:textColor="@color/text2" android:textSize="@dimen/text_sub"
|
||||
android:text="@string/connection_log" />
|
||||
</LinearLayout>
|
||||
|
||||
@@ -44,14 +44,14 @@
|
||||
android:orientation="vertical" android:gravity="center_horizontal"
|
||||
android:visibility="gone">
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:gravity="center" android:textColor="@color/text2" android:textSize="13sp"
|
||||
android:gravity="center" android:textColor="@color/text2" android:textSize="@dimen/text_sub"
|
||||
android:paddingTop="12dp"
|
||||
android:text="@string/pin_open" />
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="plex.tv/link" android:textSize="22sp" android:textStyle="bold"
|
||||
android:textColor="@color/accent" android:paddingTop="4dp" />
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:textColor="@color/text2" android:textSize="13sp" android:paddingTop="10dp"
|
||||
android:textColor="@color/text2" android:textSize="@dimen/text_sub" android:paddingTop="10dp"
|
||||
android:text="@string/pin_enter" />
|
||||
<TextView android:id="@+id/pin_code"
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
@@ -63,7 +63,7 @@
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<TextView android:id="@+id/pin_status"
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:textColor="@color/text2" android:textSize="12sp" android:paddingLeft="8dp"
|
||||
android:textColor="@color/text2" android:textSize="@dimen/text_sub" android:paddingLeft="8dp"
|
||||
android:text="@string/pin_waiting" />
|
||||
</LinearLayout>
|
||||
<Button android:id="@+id/btn_pin_check" style="@style/ButtonAccent"
|
||||
@@ -79,7 +79,7 @@
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:orientation="vertical" android:visibility="gone">
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="@string/server_address" android:textSize="18sp" android:textStyle="bold" />
|
||||
android:text="@string/server_address" android:textSize="@dimen/text_title" android:textStyle="bold" />
|
||||
<TextView style="@style/Sub" android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:singleLine="false" android:paddingTop="4dp" android:paddingBottom="10dp"
|
||||
android:text="@string/server_address_help" />
|
||||
@@ -102,7 +102,7 @@
|
||||
android:orientation="vertical" android:visibility="gone">
|
||||
<TextView android:id="@+id/choose_title"
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:textSize="18sp" android:textStyle="bold" />
|
||||
android:textSize="@dimen/text_title" android:textStyle="bold" />
|
||||
<TextView android:id="@+id/choose_sub" style="@style/Sub"
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:singleLine="false" android:paddingTop="2dp" android:paddingBottom="10dp" />
|
||||
@@ -122,7 +122,7 @@
|
||||
<ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<TextView android:id="@+id/busy_text"
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:gravity="center" android:textColor="@color/text2" android:textSize="13sp"
|
||||
android:gravity="center" android:textColor="@color/text2" android:textSize="@dimen/text_sub"
|
||||
android:paddingTop="12dp" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
android:focusable="true">
|
||||
<TextView android:id="@+id/choice_title" style="@style/Title"
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:textSize="15sp" />
|
||||
android:textSize="@dimen/text_body" />
|
||||
<TextView android:id="@+id/choice_sub" style="@style/Sub"
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
@@ -4,8 +4,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="4dp"
|
||||
android:paddingTop="14dp"
|
||||
android:paddingBottom="6dp"
|
||||
android:textColor="@color/accent"
|
||||
android:textSize="11sp"
|
||||
android:textSize="@dimen/text_small"
|
||||
android:textStyle="bold" />
|
||||
@@ -1,20 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="54dp"
|
||||
android:layout_height="@dimen/row"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingLeft="6dp"
|
||||
android:paddingRight="4dp">
|
||||
|
||||
<FrameLayout android:layout_width="44dp" android:layout_height="44dp">
|
||||
<FrameLayout android:layout_width="@dimen/row_art" android:layout_height="@dimen/row_art">
|
||||
<ImageView android:id="@+id/row_art"
|
||||
android:layout_width="44dp" android:layout_height="44dp"
|
||||
android:layout_width="@dimen/row_art" android:layout_height="@dimen/row_art"
|
||||
android:scaleType="centerCrop" />
|
||||
<TextView android:id="@+id/row_num"
|
||||
android:layout_width="44dp" android:layout_height="44dp"
|
||||
android:layout_width="@dimen/row_art" android:layout_height="@dimen/row_art"
|
||||
android:gravity="center" android:textColor="@color/text2"
|
||||
android:textSize="13sp" android:visibility="gone" />
|
||||
android:textSize="@dimen/text_sub" android:visibility="gone" />
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
@@ -23,13 +23,13 @@
|
||||
android:paddingLeft="9dp">
|
||||
<TextView android:id="@+id/row_title" style="@style/Title"
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:textSize="14sp" android:textStyle="normal" />
|
||||
android:textSize="@dimen/text_body" android:textStyle="normal" />
|
||||
<TextView android:id="@+id/row_sub" style="@style/Sub"
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView android:id="@+id/row_right"
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:textColor="@color/text2" android:textSize="11sp"
|
||||
android:textColor="@color/text2" android:textSize="@dimen/text_tiny"
|
||||
android:paddingLeft="6dp" android:paddingRight="6dp" />
|
||||
</LinearLayout>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="96dp"
|
||||
android:layout_width="@dimen/card"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="4dp"
|
||||
@@ -8,12 +8,12 @@
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
<ImageView android:id="@+id/card_art"
|
||||
android:layout_width="88dp" android:layout_height="88dp"
|
||||
android:layout_width="@dimen/card_art" android:layout_height="@dimen/card_art"
|
||||
android:scaleType="centerCrop" />
|
||||
<TextView android:id="@+id/card_title" style="@style/Title"
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:textSize="12sp" android:textStyle="normal" android:paddingTop="4dp" />
|
||||
android:textSize="@dimen/text_card_title" android:textStyle="normal" android:paddingTop="4dp" />
|
||||
<TextView android:id="@+id/card_sub" style="@style/Sub"
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:textSize="10sp" />
|
||||
android:textSize="@dimen/text_tiny" />
|
||||
</LinearLayout>
|
||||
@@ -10,7 +10,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
<ImageView android:id="@+id/detail_art"
|
||||
android:layout_width="104dp" android:layout_height="104dp"
|
||||
android:layout_width="@dimen/detail_art" android:layout_height="@dimen/detail_art"
|
||||
android:scaleType="centerCrop" />
|
||||
<LinearLayout
|
||||
android:layout_width="0dp" android:layout_height="wrap_content"
|
||||
@@ -18,11 +18,11 @@
|
||||
android:paddingLeft="12dp" android:paddingTop="4dp">
|
||||
<TextView android:id="@+id/detail_title"
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:textSize="17sp" android:textStyle="bold" android:maxLines="3"
|
||||
android:textSize="@dimen/text_detail_title" android:textStyle="bold" android:maxLines="3"
|
||||
android:ellipsize="end" android:textColor="@color/text" />
|
||||
<TextView android:id="@+id/detail_sub"
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:textSize="13sp" android:textColor="@color/accent"
|
||||
android:textSize="@dimen/text_np_sub" android:textColor="@color/accent"
|
||||
android:paddingTop="2dp" android:singleLine="true" android:ellipsize="end" />
|
||||
<TextView android:id="@+id/detail_meta" style="@style/Sub"
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
@@ -37,9 +37,11 @@
|
||||
android:paddingTop="10dp">
|
||||
<Button android:id="@+id/detail_play" style="@style/ButtonAccent"
|
||||
android:layout_width="0dp" android:layout_weight="1"
|
||||
android:layout_marginRight="5dp" android:text="@string/play" />
|
||||
android:layout_marginRight="5dp" android:text="@string/play"
|
||||
android:paddingLeft="4dp" android:paddingRight="4dp" />
|
||||
<Button android:id="@+id/detail_shuffle" style="@style/ButtonOutline"
|
||||
android:layout_width="0dp" android:layout_weight="1"
|
||||
android:layout_marginLeft="5dp" android:text="@string/shuffle" />
|
||||
android:layout_marginLeft="5dp" android:text="@string/shuffle"
|
||||
android:paddingLeft="4dp" android:paddingRight="4dp" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -1,21 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Full-width row: on a 240 px screen two side by side cut their titles short. -->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="58dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/tile"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:background="@drawable/bg_tile"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="6dp"
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingRight="10dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
<ImageView android:id="@+id/tile_icon" android:layout_width="26dp" android:layout_height="26dp" />
|
||||
<ImageView android:id="@+id/tile_icon" android:layout_width="@dimen/tile_icon" android:layout_height="@dimen/tile_icon" />
|
||||
<LinearLayout android:layout_width="0dp" android:layout_height="wrap_content"
|
||||
android:layout_weight="1" android:orientation="vertical" android:paddingLeft="7dp">
|
||||
android:layout_weight="1" android:orientation="vertical" android:paddingLeft="12dp">
|
||||
<TextView android:id="@+id/tile_title" style="@style/Title"
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="13sp" />
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="@dimen/text_tile" />
|
||||
<TextView android:id="@+id/tile_sub" style="@style/Sub"
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="10sp" />
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="@dimen/text_small" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -11,21 +11,21 @@
|
||||
android:id="@+id/mini_progress"
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:layout_height="3dp"
|
||||
android:max="1000"
|
||||
android:progressDrawable="@drawable/progress_mini" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/mini_body"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:layout_height="@dimen/mini"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:background="@drawable/bg_pressable"
|
||||
android:paddingLeft="5dp">
|
||||
|
||||
<ImageView android:id="@+id/mini_art"
|
||||
android:layout_width="40dp" android:layout_height="40dp"
|
||||
android:layout_width="@dimen/mini_art" android:layout_height="@dimen/mini_art"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
<LinearLayout
|
||||
@@ -34,10 +34,10 @@
|
||||
android:paddingLeft="8dp">
|
||||
<TextView android:id="@+id/mini_title" style="@style/Title"
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:textSize="13sp" />
|
||||
android:textSize="@dimen/text_mini_title" />
|
||||
<TextView android:id="@+id/mini_sub" style="@style/Sub"
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:textSize="11sp" />
|
||||
android:textSize="@dimen/text_mini_sub" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton android:id="@+id/mini_play" style="@style/IconButton" />
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
<TextView android:id="@+id/status_text"
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:gravity="center" android:textColor="@color/text2" android:textSize="13sp"
|
||||
android:gravity="center" android:textColor="@color/text2" android:textSize="@dimen/text_status"
|
||||
android:paddingTop="8dp" />
|
||||
<Button android:id="@+id/status_retry" style="@style/ButtonOutline"
|
||||
android:layout_width="wrap_content" android:layout_marginTop="12dp"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/topbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="46dp"
|
||||
android:layout_height="@dimen/topbar"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingLeft="4dp"
|
||||
@@ -20,7 +20,7 @@
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content" />
|
||||
<TextView android:id="@+id/bar_sub" style="@style/Sub"
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:textSize="11sp" android:visibility="gone" />
|
||||
android:textSize="@dimen/text_small" android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton android:id="@+id/btn_action" style="@style/IconButton" android:visibility="gone" />
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<string name="app_name">Minamp</string>
|
||||
<string name="applies_next_track">Applies from the next track</string>
|
||||
<string name="artist">Artist</string>
|
||||
<string name="artist_radio">Artist radio</string>
|
||||
<string name="artist_radio">Radio</string>
|
||||
<string name="artist_radio_shuffle">Artist radio (shuffle)</string>
|
||||
<string name="back">Back</string>
|
||||
<string name="buffering">Buffering…</string>
|
||||
@@ -26,7 +26,7 @@
|
||||
<string name="clear_upcoming">Clear upcoming tracks</string>
|
||||
<string name="close">Close</string>
|
||||
<string name="connect">Connect</string>
|
||||
<string name="connect_address">Connect to a server address</string>
|
||||
<string name="connect_address">Connect by address</string>
|
||||
<string name="connected_x">Connected: %1$s</string>
|
||||
<string name="connecting">Connecting…</string>
|
||||
<string name="connecting_to">Connecting to %1$s…\nTrying home network, then remote, then relay.</string>
|
||||
@@ -88,7 +88,7 @@
|
||||
<string name="paused_dot">Paused · </string>
|
||||
<string name="pick_something">Pick something from your library</string>
|
||||
<string name="pin_check_failed">Check %1$d failed: %2$s — retrying</string>
|
||||
<string name="pin_check_now">I\'ve entered it — check now</string>
|
||||
<string name="pin_check_now">Check now</string>
|
||||
<string name="pin_enter">and enter this code:</string>
|
||||
<string name="pin_expired">Code expired — press Cancel and sign in again</string>
|
||||
<string name="pin_linked">Linked!</string>
|
||||
@@ -121,7 +121,7 @@
|
||||
<string name="save_to_sd">Save to SD card</string>
|
||||
<string name="saved_log">Saved as Minamp-log.txt on the SD card</string>
|
||||
<string name="search">Search</string>
|
||||
<string name="search_hint">Artists, albums, tracks</string>
|
||||
<string name="search_hint">Search music</string>
|
||||
<string name="search_in">Search %1$s</string>
|
||||
<string name="searching">Searching…</string>
|
||||
<string name="secure"> (secure)</string>
|
||||
@@ -143,6 +143,7 @@
|
||||
<string name="set_quality_home">Quality at home: %1$s</string>
|
||||
<string name="set_secure_home">Encrypt at home too (slower): %1$s</string>
|
||||
<string name="set_server">Server: %1$s</string>
|
||||
<string name="set_size">Text and button size: %1$s</string>
|
||||
<string name="settings">Settings</string>
|
||||
<string name="shuffle">Shuffle</string>
|
||||
<string name="shuffle_off">Shuffle off</string>
|
||||
@@ -153,6 +154,10 @@
|
||||
<string name="sign_out_confirm">Sign out and forget this server?</string>
|
||||
<string name="signed_in_as">Signed in as %1$s</string>
|
||||
<string name="signed_in_finding">Signed in. Finding your servers…</string>
|
||||
<string name="size_large">Large</string>
|
||||
<string name="size_normal">Normal</string>
|
||||
<string name="size_title">Text and button size</string>
|
||||
<string name="size_xlarge">Extra large</string>
|
||||
<string name="sleep">Sleep</string>
|
||||
<string name="sleep_15">15 minutes</string>
|
||||
<string name="sleep_30">30 minutes</string>
|
||||
@@ -173,10 +178,10 @@
|
||||
<string name="starting_x">Starting %1$s…</string>
|
||||
<string name="stream_interrupted">Stream interrupted</string>
|
||||
<string name="surprise_me">Surprise me</string>
|
||||
<string name="tab_albums">ALBUMS</string>
|
||||
<string name="tab_artists">ARTISTS</string>
|
||||
<string name="tab_home">HOME</string>
|
||||
<string name="tab_playlists">PLAYLISTS</string>
|
||||
<string name="tab_albums">Albums</string>
|
||||
<string name="tab_artists">Artists</string>
|
||||
<string name="tab_home">Home</string>
|
||||
<string name="tab_playlists">Playlists</string>
|
||||
<string name="tagline">Your Plex music, anywhere,\non a very small phone.</string>
|
||||
<string name="test_streaming">Test streaming</string>
|
||||
<string name="testing">Testing… (about 30 s)</string>
|
||||
@@ -204,6 +209,6 @@
|
||||
<string name="unencrypted"> (unencrypted)</string>
|
||||
<string name="unlove">Remove from favourites</string>
|
||||
<string name="unloved">Removed from favourites</string>
|
||||
<string name="up_next">Up next</string>
|
||||
<string name="up_next">Queue</string>
|
||||
<string name="you">you</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- All UI sizes in one place. tools/check_fit.py reads these to check that texts fit. -->
|
||||
<resources>
|
||||
<!-- text -->
|
||||
<dimen name="text_tiny">12sp</dimen> <!-- times, "PLAYING FROM", card subtitles -->
|
||||
<dimen name="text_small">13sp</dimen> <!-- section headers, tile subtitles -->
|
||||
<dimen name="text_tab">13sp</dimen>
|
||||
<dimen name="text_sub">14sp</dimen> <!-- secondary lines -->
|
||||
<dimen name="text_body">16sp</dimen> <!-- list titles, fields -->
|
||||
<dimen name="text_button">16sp</dimen>
|
||||
<dimen name="text_tile">15sp</dimen>
|
||||
<dimen name="text_status">15sp</dimen>
|
||||
<dimen name="text_title">18sp</dimen> <!-- top bar -->
|
||||
<dimen name="text_detail_title">20sp</dimen>
|
||||
<dimen name="text_np_title">21sp</dimen>
|
||||
<dimen name="text_np_sub">15sp</dimen>
|
||||
<dimen name="text_np_small">14sp</dimen>
|
||||
<dimen name="text_mini_title">15sp</dimen>
|
||||
<dimen name="text_mini_sub">13sp</dimen>
|
||||
<dimen name="text_card_title">13sp</dimen>
|
||||
<dimen name="text_log">11sp</dimen>
|
||||
|
||||
<!-- touch targets and bars -->
|
||||
<dimen name="touch">48dp</dimen>
|
||||
<dimen name="topbar">54dp</dimen>
|
||||
<dimen name="tabs">42dp</dimen>
|
||||
<dimen name="button">48dp</dimen>
|
||||
<dimen name="button_pad">10dp</dimen>
|
||||
<dimen name="row">66dp</dimen>
|
||||
<dimen name="row_art">52dp</dimen>
|
||||
<dimen name="mini">62dp</dimen>
|
||||
<dimen name="mini_art">48dp</dimen>
|
||||
<dimen name="tile">62dp</dimen>
|
||||
<dimen name="tile_icon">28dp</dimen>
|
||||
<dimen name="card">110dp</dimen>
|
||||
<dimen name="card_art">102dp</dimen>
|
||||
<dimen name="detail_art">112dp</dimen>
|
||||
|
||||
<!-- now playing -->
|
||||
<dimen name="np_topbar">50dp</dimen>
|
||||
<dimen name="np_controls">70dp</dimen>
|
||||
<dimen name="np_play">64dp</dimen>
|
||||
<dimen name="np_small_icon">22dp</dimen>
|
||||
<dimen name="np_bottom">44dp</dimen>
|
||||
<dimen name="seek_track">6dp</dimen>
|
||||
<dimen name="seek_thumb">20dp</dimen>
|
||||
</resources>
|
||||
+19
-14
@@ -10,7 +10,7 @@
|
||||
<string name="app_name">Minamp</string>
|
||||
<string name="applies_next_track">Aplícase desde a seguinte pista</string>
|
||||
<string name="artist">Artista</string>
|
||||
<string name="artist_radio">Radio do artista</string>
|
||||
<string name="artist_radio">Radio</string>
|
||||
<string name="artist_radio_shuffle">Radio do artista (aleatorio)</string>
|
||||
<string name="back">Volver</string>
|
||||
<string name="buffering">Cargando…</string>
|
||||
@@ -26,7 +26,7 @@
|
||||
<string name="clear_upcoming">Borrar as pistas seguintes</string>
|
||||
<string name="close">Pechar</string>
|
||||
<string name="connect">Conectar</string>
|
||||
<string name="connect_address">Conectar a un enderezo de servidor</string>
|
||||
<string name="connect_address">Conectar por enderezo</string>
|
||||
<string name="connected_x">Conectado: %1$s</string>
|
||||
<string name="connecting">Conectando…</string>
|
||||
<string name="connecting_to">Conectando con %1$s…\nProbando a rede da casa, despois a remota e despois o relay.</string>
|
||||
@@ -88,7 +88,7 @@
|
||||
<string name="paused_dot">En pausa · </string>
|
||||
<string name="pick_something">Escolle algo da túa biblioteca</string>
|
||||
<string name="pin_check_failed">Fallou a comprobación %1$d: %2$s; tentando de novo</string>
|
||||
<string name="pin_check_now">Xa o escribín: comprobar agora</string>
|
||||
<string name="pin_check_now">Comprobar agora</string>
|
||||
<string name="pin_enter">e escribe este código:</string>
|
||||
<string name="pin_expired">O código caducou: preme Cancelar e inicia sesión de novo</string>
|
||||
<string name="pin_linked">Vinculado!</string>
|
||||
@@ -96,7 +96,7 @@
|
||||
<string name="pin_open">Nun ordenador ou nun teléfono máis novo, abre</string>
|
||||
<string name="pin_waiting">Agardando a que vincules a conta…</string>
|
||||
<string name="play">Reproducir</string>
|
||||
<string name="play_all">Reproducir todo</string>
|
||||
<string name="play_all">Reproducir</string>
|
||||
<string name="play_next">Reproducir a continuación</string>
|
||||
<string name="playback_error">Erro de reprodución (%1$d/%2$d)</string>
|
||||
<string name="playing_from">REPRODUCINDO DESDE</string>
|
||||
@@ -110,8 +110,8 @@
|
||||
<string name="queue_empty">A cola está baleira</string>
|
||||
<string name="random_album">Álbum ao chou</string>
|
||||
<string name="random_album_sub">Proba sorte</string>
|
||||
<string name="recently_added">Engadidos recentemente</string>
|
||||
<string name="recently_played">Escoitados recentemente</string>
|
||||
<string name="recently_added">Novidades</string>
|
||||
<string name="recently_played">Últimas escoitas</string>
|
||||
<string name="reconnecting">Reconectando…</string>
|
||||
<string name="refresh">Actualizar</string>
|
||||
<string name="remove_from_queue">Quitar da cola</string>
|
||||
@@ -121,7 +121,7 @@
|
||||
<string name="save_to_sd">Gardar na tarxeta SD</string>
|
||||
<string name="saved_log">Gardado como Minamp-log.txt na tarxeta SD</string>
|
||||
<string name="search">Buscar</string>
|
||||
<string name="search_hint">Artistas, álbums, cancións</string>
|
||||
<string name="search_hint">Buscar música</string>
|
||||
<string name="search_in">Buscar en %1$s</string>
|
||||
<string name="searching">Buscando…</string>
|
||||
<string name="secure"> (cifrada)</string>
|
||||
@@ -143,6 +143,7 @@
|
||||
<string name="set_quality_home">Calidade na casa: %1$s</string>
|
||||
<string name="set_secure_home">Cifrar tamén na casa (máis lento): %1$s</string>
|
||||
<string name="set_server">Servidor: %1$s</string>
|
||||
<string name="set_size">Tamaño de texto e botóns: %1$s</string>
|
||||
<string name="settings">Axustes</string>
|
||||
<string name="shuffle">Aleatorio</string>
|
||||
<string name="shuffle_off">Aleatorio desactivado</string>
|
||||
@@ -153,7 +154,11 @@
|
||||
<string name="sign_out_confirm">Pechar sesión e esquecer este servidor?</string>
|
||||
<string name="signed_in_as">Sesión iniciada como %1$s</string>
|
||||
<string name="signed_in_finding">Sesión iniciada. Buscando os teus servidores…</string>
|
||||
<string name="sleep">Temporizador</string>
|
||||
<string name="size_large">Grande</string>
|
||||
<string name="size_normal">Normal</string>
|
||||
<string name="size_title">Tamaño de texto e botóns</string>
|
||||
<string name="size_xlarge">Moi grande</string>
|
||||
<string name="sleep">Durmir</string>
|
||||
<string name="sleep_15">15 minutos</string>
|
||||
<string name="sleep_30">30 minutos</string>
|
||||
<string name="sleep_45">45 minutos</string>
|
||||
@@ -173,15 +178,15 @@
|
||||
<string name="starting_x">Iniciando %1$s…</string>
|
||||
<string name="stream_interrupted">Interrompeuse a transmisión</string>
|
||||
<string name="surprise_me">Sorpréndeme</string>
|
||||
<string name="tab_albums">ÁLBUMS</string>
|
||||
<string name="tab_artists">ARTISTAS</string>
|
||||
<string name="tab_home">INICIO</string>
|
||||
<string name="tab_playlists">LISTAS</string>
|
||||
<string name="tab_albums">Álbums</string>
|
||||
<string name="tab_artists">Artistas</string>
|
||||
<string name="tab_home">Inicio</string>
|
||||
<string name="tab_playlists">Listas</string>
|
||||
<string name="tagline">A túa música de Plex, onde queiras,\nnun teléfono moi pequeno.</string>
|
||||
<string name="test_streaming">Probar reprodución</string>
|
||||
<string name="testing">Probando… (uns 30 s)</string>
|
||||
<string name="time_travel">Viaxe no tempo</string>
|
||||
<string name="time_travel_sub">Escolle unha década</string>
|
||||
<string name="time_travel_sub">Escolle década</string>
|
||||
<string name="time_travel_title">Radio viaxe no tempo</string>
|
||||
<string name="token_hint">X-Plex-Token (opcional na rede da casa)</string>
|
||||
<string name="tr_artist">Artista</string>
|
||||
@@ -204,6 +209,6 @@
|
||||
<string name="unencrypted"> (sen cifrar)</string>
|
||||
<string name="unlove">Quitar de favoritas</string>
|
||||
<string name="unloved">Quitada de favoritas</string>
|
||||
<string name="up_next">A continuación</string>
|
||||
<string name="up_next">Cola</string>
|
||||
<string name="you">ti</string>
|
||||
</resources>
|
||||
+17
-10
@@ -18,7 +18,7 @@
|
||||
</style>
|
||||
|
||||
<style name="Title">
|
||||
<item name="android:textSize">16sp</item>
|
||||
<item name="android:textSize">@dimen/text_title</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
<item name="android:textColor">@color/text</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
@@ -26,7 +26,7 @@
|
||||
</style>
|
||||
|
||||
<style name="Sub">
|
||||
<item name="android:textSize">12sp</item>
|
||||
<item name="android:textSize">@dimen/text_sub</item>
|
||||
<item name="android:textColor">@color/text2</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
<item name="android:ellipsize">end</item>
|
||||
@@ -37,29 +37,35 @@
|
||||
<item name="android:layout_height">match_parent</item>
|
||||
<item name="android:layout_weight">1</item>
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:textSize">11sp</item>
|
||||
<item name="android:textSize">@dimen/text_tab</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
<item name="android:textColor">@color/text2</item>
|
||||
<item name="android:background">@drawable/bg_pressable</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
<item name="android:ellipsize">end</item>
|
||||
</style>
|
||||
|
||||
<style name="IconButton">
|
||||
<item name="android:layout_width">44dp</item>
|
||||
<item name="android:layout_height">44dp</item>
|
||||
<item name="android:layout_width">@dimen/touch</item>
|
||||
<item name="android:layout_height">@dimen/touch</item>
|
||||
<item name="android:background">@drawable/bg_pressable_round</item>
|
||||
<item name="android:scaleType">center</item>
|
||||
</style>
|
||||
|
||||
<!-- full-width buttons may wrap to two lines rather than cut words off -->
|
||||
<style name="ButtonAccent">
|
||||
<item name="android:layout_height">40dp</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:minHeight">@dimen/button</item>
|
||||
<item name="android:background">@drawable/bg_button_accent</item>
|
||||
<item name="android:textColor">@color/on_accent</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="android:textSize">@dimen/text_button</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:paddingLeft">16dp</item>
|
||||
<item name="android:paddingRight">16dp</item>
|
||||
<item name="android:maxLines">2</item>
|
||||
<item name="android:paddingLeft">@dimen/button_pad</item>
|
||||
<item name="android:paddingRight">@dimen/button_pad</item>
|
||||
<item name="android:paddingTop">6dp</item>
|
||||
<item name="android:paddingBottom">6dp</item>
|
||||
</style>
|
||||
|
||||
<style name="ButtonOutline" parent="ButtonAccent">
|
||||
@@ -70,10 +76,11 @@
|
||||
<style name="Edit">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:minHeight">@dimen/button</item>
|
||||
<item name="android:background">@drawable/bg_edit</item>
|
||||
<item name="android:textColor">@color/text</item>
|
||||
<item name="android:textColorHint">@color/text2</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="android:textSize">@dimen/text_body</item>
|
||||
<item name="android:padding">10dp</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
</style>
|
||||
|
||||
+25
-4
@@ -111,7 +111,18 @@ public class App extends Application {
|
||||
return code;
|
||||
}
|
||||
|
||||
/** Forces the app's language on a context's resources (call before inflating any layout). */
|
||||
/** UI size: everything (text, icons, buttons) is scaled by this on top of the phone's density. */
|
||||
public static final float[] UI_SCALES = {1.0f, 1.15f, 1.3f};
|
||||
|
||||
public int uiScaleIndex() {
|
||||
int i = prefs.getInt("uiScale", 0);
|
||||
return i < 0 || i >= UI_SCALES.length ? 0 : i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces the app's language and UI size on a context's resources (call before inflating any
|
||||
* layout). The phone's own density comes from the system resources, which are never touched.
|
||||
*/
|
||||
public static void applyLanguage(android.content.Context c) {
|
||||
App app = instance;
|
||||
if (app == null) return;
|
||||
@@ -119,9 +130,19 @@ public class App extends Application {
|
||||
java.util.Locale.setDefault(loc);
|
||||
android.content.res.Resources r = c.getResources();
|
||||
android.content.res.Configuration cfg = r.getConfiguration();
|
||||
if (loc.equals(cfg.locale)) return;
|
||||
cfg.locale = loc;
|
||||
r.updateConfiguration(cfg, r.getDisplayMetrics());
|
||||
android.util.DisplayMetrics dm = r.getDisplayMetrics();
|
||||
float base = android.content.res.Resources.getSystem().getDisplayMetrics().density;
|
||||
float want = base * UI_SCALES[app.uiScaleIndex()];
|
||||
boolean localeOk = loc.equals(cfg.locale);
|
||||
boolean sizeOk = Math.abs(dm.density - want) < 0.001f;
|
||||
if (localeOk && sizeOk) return;
|
||||
// a copy, so Resources sees what changed (and drops resources cached for the old locale)
|
||||
android.content.res.Configuration nc = new android.content.res.Configuration(cfg);
|
||||
nc.locale = loc;
|
||||
dm.density = want;
|
||||
dm.densityDpi = (int) (want * 160 + 0.5f);
|
||||
dm.scaledDensity = want * (nc.fontScale > 0 ? nc.fontScale : 1f);
|
||||
r.updateConfiguration(nc, dm);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -87,7 +87,7 @@ public abstract class BaseActivity extends Activity implements PlayerService.Lis
|
||||
android.widget.ScrollView sv = new android.widget.ScrollView(this);
|
||||
TextView tv = new TextView(this);
|
||||
tv.setText(report);
|
||||
tv.setTextSize(10);
|
||||
tv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.text_log) + Ui.dp(this, 1));
|
||||
tv.setTextColor(0xFFDDDDDD);
|
||||
int p = Ui.dp(this, 8);
|
||||
tv.setPadding(p, p, p, p);
|
||||
@@ -196,11 +196,11 @@ public abstract class BaseActivity extends Activity implements PlayerService.Lis
|
||||
miniSub = (TextView) findViewById(R.id.mini_sub);
|
||||
miniPlay = (ImageButton) findViewById(R.id.mini_play);
|
||||
miniProgress = (ProgressBar) findViewById(R.id.mini_progress);
|
||||
miniPlayGlyph = Ui.glyph(this, Glyph.PLAY, getResources().getColor(R.color.text), 18);
|
||||
miniPlayGlyph = Ui.glyph(this, Glyph.PLAY, getResources().getColor(R.color.text), 24);
|
||||
miniPlayGlyph.scale(1f);
|
||||
miniPlay.setImageDrawable(miniPlayGlyph);
|
||||
ImageButton next = (ImageButton) findViewById(R.id.mini_next);
|
||||
Ui.icon(next, Glyph.NEXT, getResources().getColor(R.color.text), 16);
|
||||
Ui.icon(next, Glyph.NEXT, getResources().getColor(R.color.text), 21);
|
||||
miniPlay.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) { PlayerService.send(BaseActivity.this, PlayerService.ACTION_TOGGLE); }
|
||||
});
|
||||
@@ -225,7 +225,7 @@ public abstract class BaseActivity extends Activity implements PlayerService.Lis
|
||||
miniPlayGlyph.setType(PlayerService.isPlaying() ? Glyph.PAUSE : Glyph.PLAY);
|
||||
if (!it.thumb.equals(miniThumb)) {
|
||||
miniThumb = it.thumb;
|
||||
app.images.load(miniArt, it.thumb, Ui.dp(this, 40), R.drawable.art_placeholder);
|
||||
app.images.load(miniArt, it.thumb, Ui.dimen(this, R.dimen.mini_art), R.drawable.art_placeholder);
|
||||
}
|
||||
updateMiniProgress();
|
||||
}
|
||||
@@ -404,6 +404,7 @@ public abstract class BaseActivity extends Activity implements PlayerService.Lis
|
||||
str(R.string.set_connection, conn),
|
||||
str(R.string.set_log),
|
||||
str(R.string.set_language, App.languageName(app.language())),
|
||||
str(R.string.set_size, sizeLabels()[app.uiScaleIndex()]),
|
||||
str(R.string.sign_out),
|
||||
};
|
||||
new AlertDialog.Builder(this)
|
||||
@@ -439,7 +440,8 @@ public abstract class BaseActivity extends Activity implements PlayerService.Lis
|
||||
break;
|
||||
case 7: showDiagnostics(); break;
|
||||
case 8: pickLanguage(); break;
|
||||
case 9: confirmSignOut(); break;
|
||||
case 9: pickSize(); break;
|
||||
case 10: confirmSignOut(); break;
|
||||
}
|
||||
}
|
||||
}).show();
|
||||
@@ -453,7 +455,7 @@ public abstract class BaseActivity extends Activity implements PlayerService.Lis
|
||||
protected void showDiagnostics() {
|
||||
final android.widget.ScrollView sv = new android.widget.ScrollView(this);
|
||||
final TextView tv = new TextView(this);
|
||||
tv.setTextSize(9);
|
||||
tv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.text_log));
|
||||
tv.setTextColor(0xFFDDDDDD);
|
||||
tv.setTypeface(android.graphics.Typeface.MONOSPACE);
|
||||
int p = Ui.dp(this, 6);
|
||||
@@ -576,6 +578,34 @@ public abstract class BaseActivity extends Activity implements PlayerService.Lis
|
||||
return l;
|
||||
}
|
||||
|
||||
private String[] sizeLabels() {
|
||||
return new String[] {str(R.string.size_normal), str(R.string.size_large), str(R.string.size_xlarge)};
|
||||
}
|
||||
|
||||
private void pickSize() {
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.size_title)
|
||||
.setSingleChoiceItems(sizeLabels(), app.uiScaleIndex(), new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface d, int which) {
|
||||
d.dismiss();
|
||||
if (which == app.uiScaleIndex()) return;
|
||||
app.prefs.edit().putInt("uiScale", which).commit();
|
||||
relaunchUi();
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
|
||||
/** Rebuilds all screens so a new language or size takes effect everywhere. */
|
||||
private void relaunchUi() {
|
||||
App.applyLanguage(getApplicationContext());
|
||||
App.applyLanguage(BaseActivity.this);
|
||||
app.images.clearMemory(); // artwork is cached at the old pixel sizes
|
||||
startActivity(new Intent(BaseActivity.this, HomeActivity.class)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP).putExtra("relaunch", true));
|
||||
// HomeActivity rebuilds itself when it gets the "relaunch" intent; anything else just closes
|
||||
if (!(this instanceof HomeActivity)) finish();
|
||||
}
|
||||
|
||||
private void pickLanguage() {
|
||||
int sel = 0;
|
||||
for (int i = 0; i < App.LANGUAGES.length; i++) if (App.LANGUAGES[i].equals(app.language())) sel = i;
|
||||
@@ -586,12 +616,7 @@ public abstract class BaseActivity extends Activity implements PlayerService.Lis
|
||||
d.dismiss();
|
||||
if (App.LANGUAGES[which].equals(app.language())) return;
|
||||
app.prefs.edit().putString("lang", App.LANGUAGES[which]).commit();
|
||||
App.applyLanguage(getApplicationContext());
|
||||
App.applyLanguage(BaseActivity.this);
|
||||
// rebuild the screens in the new language
|
||||
startActivity(new Intent(BaseActivity.this, HomeActivity.class)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP).putExtra("relaunch", true));
|
||||
finish();
|
||||
relaunchUi();
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ public class BrowseActivity extends BaseActivity {
|
||||
public void onClick(View v) { openKey(item.artistKey, Item.ARTIST, item.artist); }
|
||||
});
|
||||
}
|
||||
app.images.load((ImageView) header.findViewById(R.id.detail_art), item.thumb, Ui.dp(this, 104), R.drawable.art_placeholder);
|
||||
app.images.load((ImageView) header.findViewById(R.id.detail_art), item.thumb, Ui.dimen(this, R.dimen.detail_art), R.drawable.art_placeholder);
|
||||
}
|
||||
|
||||
private void setMeta(List<Item> children) {
|
||||
|
||||
@@ -168,7 +168,8 @@ public class HomeActivity extends BaseActivity {
|
||||
runRadio(str(R.string.library_radio), new Task<List<Item>>() { public List<Item> work() throws Exception { return lib.libraryRadio(); } });
|
||||
}
|
||||
}));
|
||||
row1.addView(spacer());
|
||||
homeContent.addView(row1);
|
||||
row1 = tileRow();
|
||||
row1.addView(tile(inf, Glyph.HEART, str(R.string.loved_radio), str(R.string.loved_radio_sub), new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
final Library lib = lib();
|
||||
@@ -181,7 +182,8 @@ public class HomeActivity extends BaseActivity {
|
||||
row2.addView(tile(inf, Glyph.CLOCK, str(R.string.time_travel), str(R.string.time_travel_sub), new View.OnClickListener() {
|
||||
public void onClick(View v) { timeTravel(); }
|
||||
}));
|
||||
row2.addView(spacer());
|
||||
homeContent.addView(row2);
|
||||
row2 = tileRow();
|
||||
row2.addView(tile(inf, Glyph.SHUFFLE, str(R.string.random_album), str(R.string.random_album_sub), new View.OnClickListener() {
|
||||
public void onClick(View v) { randomAlbum(); }
|
||||
}));
|
||||
@@ -196,20 +198,14 @@ public class HomeActivity extends BaseActivity {
|
||||
LinearLayout r = new LinearLayout(this);
|
||||
r.setOrientation(LinearLayout.HORIZONTAL);
|
||||
int p = Ui.dp(this, 8);
|
||||
r.setPadding(p, p / 2, p, p / 2);
|
||||
r.setPadding(p, p / 4, p, p / 4);
|
||||
return r;
|
||||
}
|
||||
|
||||
private View spacer() {
|
||||
View v = new View(this);
|
||||
v.setLayoutParams(new LinearLayout.LayoutParams(Ui.dp(this, 8), 1));
|
||||
return v;
|
||||
}
|
||||
|
||||
private View tile(LayoutInflater inf, int glyph, String title, String sub, View.OnClickListener l) {
|
||||
View t = inf.inflate(R.layout.view_home_tile, null);
|
||||
t.setLayoutParams(new LinearLayout.LayoutParams(0, Ui.dp(this, 56), 1f));
|
||||
Ui.icon((ImageView) t.findViewById(R.id.tile_icon), glyph, getResources().getColor(R.color.accent), 22);
|
||||
t.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Ui.dimen(this, R.dimen.tile)));
|
||||
Ui.icon((ImageView) t.findViewById(R.id.tile_icon), glyph, getResources().getColor(R.color.accent), 26);
|
||||
((TextView) t.findViewById(R.id.tile_title)).setText(title);
|
||||
((TextView) t.findViewById(R.id.tile_sub)).setText(sub);
|
||||
t.setOnClickListener(l);
|
||||
@@ -249,7 +245,7 @@ public class HomeActivity extends BaseActivity {
|
||||
final TextView loading = new TextView(this);
|
||||
loading.setText(R.string.loading);
|
||||
loading.setTextColor(getResources().getColor(R.color.text2));
|
||||
loading.setTextSize(12);
|
||||
loading.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.text_sub));
|
||||
loading.setPadding(Ui.dp(this, 6), Ui.dp(this, 30), 0, Ui.dp(this, 30));
|
||||
strip.addView(loading);
|
||||
homeContent.addView(hs);
|
||||
@@ -261,7 +257,7 @@ public class HomeActivity extends BaseActivity {
|
||||
strip.removeAllViews();
|
||||
if (items.isEmpty()) { loading.setText(R.string.nothing_here_yet); strip.addView(loading); return; }
|
||||
LayoutInflater li = getLayoutInflater();
|
||||
int art = Ui.dp(HomeActivity.this, 88);
|
||||
int art = Ui.dimen(HomeActivity.this, R.dimen.card_art);
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
final Item it = items.get(i);
|
||||
View card = li.inflate(R.layout.view_album_card, strip, false);
|
||||
|
||||
@@ -37,7 +37,7 @@ public class ItemAdapter extends BaseAdapter {
|
||||
ctx = c;
|
||||
this.mode = mode;
|
||||
inflater = LayoutInflater.from(c);
|
||||
artPx = Ui.dp(c, 44);
|
||||
artPx = Ui.dimen(c, R.dimen.row_art);
|
||||
accent = c.getResources().getColor(R.color.accent);
|
||||
text = c.getResources().getColor(R.color.text);
|
||||
app = App.get();
|
||||
|
||||
@@ -59,7 +59,7 @@ public class NowPlayingActivity extends BaseActivity {
|
||||
public void onClick(View v) { startActivity(new Intent(NowPlayingActivity.this, QueueActivity.class)); }
|
||||
});
|
||||
|
||||
playGlyph = Ui.glyph(this, Glyph.PLAY, getResources().getColor(R.color.on_accent), 24);
|
||||
playGlyph = Ui.glyph(this, Glyph.PLAY, getResources().getColor(R.color.on_accent), 28);
|
||||
playGlyph.scale(1f);
|
||||
playBtn.setImageDrawable(playGlyph);
|
||||
playBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@@ -67,8 +67,8 @@ public class NowPlayingActivity extends BaseActivity {
|
||||
});
|
||||
ImageButton prev = (ImageButton) findViewById(R.id.np_prev);
|
||||
ImageButton next = (ImageButton) findViewById(R.id.np_next);
|
||||
Ui.icon(prev, Glyph.PREV, white, 22);
|
||||
Ui.icon(next, Glyph.NEXT, white, 22);
|
||||
Ui.icon(prev, Glyph.PREV, white, 26);
|
||||
Ui.icon(next, Glyph.NEXT, white, 26);
|
||||
prev.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) { PlayerService.send(NowPlayingActivity.this, PlayerService.ACTION_PREV); }
|
||||
});
|
||||
@@ -76,12 +76,12 @@ public class NowPlayingActivity extends BaseActivity {
|
||||
public void onClick(View v) { PlayerService.send(NowPlayingActivity.this, PlayerService.ACTION_NEXT); }
|
||||
});
|
||||
|
||||
shuffleGlyph = Ui.glyph(this, Glyph.SHUFFLE, dim, 20); shuffleGlyph.scale(1f);
|
||||
shuffleGlyph = Ui.glyph(this, Glyph.SHUFFLE, dim, 25); shuffleGlyph.scale(1f);
|
||||
shuffleBtn.setImageDrawable(shuffleGlyph);
|
||||
shuffleBtn.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) { PlayQueue.get().setShuffle(!PlayQueue.get().shuffle()); }
|
||||
});
|
||||
repeatGlyph = Ui.glyph(this, Glyph.REPEAT, dim, 20); repeatGlyph.scale(1f);
|
||||
repeatGlyph = Ui.glyph(this, Glyph.REPEAT, dim, 25); repeatGlyph.scale(1f);
|
||||
repeatBtn.setImageDrawable(repeatGlyph);
|
||||
repeatBtn.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
@@ -90,7 +90,7 @@ public class NowPlayingActivity extends BaseActivity {
|
||||
toast(str(r == PlayQueue.REPEAT_ALL ? R.string.repeat_queue : r == PlayQueue.REPEAT_ONE ? R.string.repeat_track : R.string.repeat_off));
|
||||
}
|
||||
});
|
||||
loveGlyph = Ui.glyph(this, Glyph.HEART_OUTLINE, white, 20); loveGlyph.scale(1f);
|
||||
loveGlyph = Ui.glyph(this, Glyph.HEART_OUTLINE, white, 25); loveGlyph.scale(1f);
|
||||
loveBtn.setImageDrawable(loveGlyph);
|
||||
loveBtn.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
@@ -99,7 +99,7 @@ public class NowPlayingActivity extends BaseActivity {
|
||||
}
|
||||
});
|
||||
|
||||
Ui.icon((ImageView) findViewById(R.id.np_sleep_icon), Glyph.MOON, 0xB3FFFFFF, 16);
|
||||
Ui.icon((ImageView) findViewById(R.id.np_sleep_icon), Glyph.MOON, 0xCCFFFFFF, 20);
|
||||
findViewById(R.id.np_sleep).setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) { sleepDialog(); }
|
||||
});
|
||||
@@ -117,6 +117,15 @@ public class NowPlayingActivity extends BaseActivity {
|
||||
}
|
||||
});
|
||||
|
||||
// knob drawn here, not from XML: Android 2.x caches XML shapes at the size they were first loaded
|
||||
int knob = Ui.dimen(this, R.dimen.seek_thumb);
|
||||
GradientDrawable thumb = new GradientDrawable();
|
||||
thumb.setShape(GradientDrawable.OVAL);
|
||||
thumb.setColor(white);
|
||||
thumb.setSize(knob, knob);
|
||||
seek.setThumb(thumb);
|
||||
seek.setThumbOffset(knob / 2);
|
||||
|
||||
seek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
public void onProgressChanged(SeekBar s, int p, boolean user) {
|
||||
if (user) {
|
||||
|
||||
@@ -26,7 +26,12 @@ public final class Ui {
|
||||
}
|
||||
|
||||
public static void icon(ImageButton v, int type, int color) {
|
||||
icon(v, type, color, 20);
|
||||
icon(v, type, color, 24);
|
||||
}
|
||||
|
||||
/** A size from res/values/dimens.xml, in pixels. */
|
||||
public static int dimen(Context c, int id) {
|
||||
return c.getResources().getDimensionPixelSize(id);
|
||||
}
|
||||
|
||||
public static String time(long ms) {
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
"""Checks that UI texts fit their slots on a 240x320 ldpi screen, in every language and UI size.
|
||||
|
||||
Uses Droid Sans (Android 2.x's system font) metrics. A slot's width is computed from the screen
|
||||
width in dp, which shrinks as the UI scale grows (240 px / (0.75 * scale)). Texts that are
|
||||
expected to ellipsize (album titles etc.) aren't checked; fixed UI words are.
|
||||
Run: python3 tools/check_fit.py [font_dir]
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
from PIL import ImageFont
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from strings import S # noqa: E402
|
||||
|
||||
FONT_DIR = sys.argv[1] if len(sys.argv) > 1 else "/home/claude/tools/fonts/x/connect-fonts-droidsans/package/fonts/latin"
|
||||
REG = ImageFont.truetype(os.path.join(FONT_DIR, "droidsans-regular.ttf"), 200)
|
||||
BOLD = ImageFont.truetype(os.path.join(FONT_DIR, "droidsans-bold.ttf"), 200)
|
||||
SCALES = {"Normal": 1.0, "Grande": 1.15, "Moi grande": 1.3} # keep in sync with App.UI_SCALES
|
||||
SCREEN_PX = 240
|
||||
LDPI = 0.75
|
||||
SAFETY = 1.04 # hinting / rounding headroom
|
||||
|
||||
|
||||
def width_dp(text, sp, bold):
|
||||
f = BOLD if bold else REG
|
||||
return f.getlength(text) * sp / 200.0 * SAFETY
|
||||
|
||||
|
||||
def lines_needed(text, sp, bold, avail):
|
||||
words = text.replace("\n", " \n ").split(" ")
|
||||
lines, cur = 1, ""
|
||||
for w in words:
|
||||
if w == "\n":
|
||||
lines += 1
|
||||
cur = ""
|
||||
continue
|
||||
trial = (cur + " " + w).strip()
|
||||
if width_dp(trial, sp, bold) <= avail:
|
||||
cur = trial
|
||||
else:
|
||||
if cur:
|
||||
lines += 1
|
||||
cur = w
|
||||
if width_dp(w, sp, bold) > avail:
|
||||
return 99 # a single word doesn't fit
|
||||
return lines
|
||||
|
||||
|
||||
def texts(keys, fmt_args=()):
|
||||
out = []
|
||||
for k in keys:
|
||||
en, gl = S[k]
|
||||
for lang, t in (("en", en), ("gl", gl)):
|
||||
if fmt_args:
|
||||
try:
|
||||
t = t.replace("%1$s", fmt_args[0]).replace("%1$d", fmt_args[0]).replace("%2$d", fmt_args[1] if len(fmt_args) > 1 else "")
|
||||
except Exception:
|
||||
pass
|
||||
out.append((k, lang, t))
|
||||
return out
|
||||
|
||||
|
||||
# slot: (name, keys, sp, bold, width_fn(screen_dp), max_lines, fmt_args)
|
||||
def slots(D):
|
||||
sw = lambda W: W # noqa: E731
|
||||
return [
|
||||
("tab", ["tab_home", "tab_artists", "tab_albums", "tab_playlists"], D["text_tab"], True,
|
||||
lambda W: W / 4 - 4, 1, ()),
|
||||
("detail button", ["play", "shuffle", "play_all", "artist_radio"], D["text_button"], True,
|
||||
lambda W: (W - 2 * 10 - 10) / 2 - 2 * 4, 1, ()),
|
||||
("home tile title", ["library_radio", "loved_radio", "time_travel", "random_album"], D["text_tile"], True,
|
||||
lambda W: W - 2 * 8 - 12 - 10 - D["tile_icon"] - 12, 1, ()),
|
||||
("home tile sub", ["library_radio_sub", "loved_radio_sub", "time_travel_sub", "random_album_sub"], D["text_small"], False,
|
||||
lambda W: W - 2 * 8 - 12 - 10 - D["tile_icon"] - 12, 1, ()),
|
||||
("shelf header + see all", ["recently_added", "recently_played"], D["text_small"], True,
|
||||
lambda W: W - 10 - width_dp(S["see_all"][1], D["text_small"], True) - 20, 1, ()),
|
||||
("now playing: playing from", ["playing_from"], D["text_tiny"], True,
|
||||
lambda W: W - 2 * D["touch"] - 8, 1, ()),
|
||||
("now playing: sleep", ["sleep", "end_of_track"], D["text_np_small"], False,
|
||||
lambda W: W - 16 - 16 - D["np_small_icon"] - 6 - width_dp(S["album_link"][1], D["text_np_small"], False) - 16, 1, ()),
|
||||
("now playing: album link", ["album_link"], D["text_np_small"], False,
|
||||
lambda W: (W - 24) / 2 - 16, 1, ()),
|
||||
("setup button", ["sign_in", "connect_address", "pin_check_now", "cancel", "connect", "back"], D["text_button"], True,
|
||||
lambda W: W - 2 * 20 - 2 * D["button_pad"], 1, ()),
|
||||
("settings: size options", ["size_normal", "size_large", "size_xlarge"], 18, False, lambda W: W - 80, 1, ()),
|
||||
("setup tagline", ["tagline"], D["text_sub"], False, lambda W: W - 40, 3, ()),
|
||||
("pin status", ["pin_not_yet"], D["text_sub"], False, lambda W: W - 40 - 24, 3, ("12", "11")),
|
||||
("pin instructions", ["pin_open"], D["text_sub"], False, lambda W: W - 40, 2, ()),
|
||||
("queue title", ["up_next"], D["text_title"], True, lambda W: W - 3 * D["touch"] - 12, 1, ()),
|
||||
("search hint", ["search_hint"], D["text_body"], False, lambda W: W - D["touch"] - 12 - 20, 1, ()),
|
||||
("status message", ["queue_empty", "no_playlists", "pick_something", "nothing_playing"], D["text_status"], False,
|
||||
lambda W: W - 48, 2, ()),
|
||||
]
|
||||
|
||||
|
||||
def run(D):
|
||||
bad = 0
|
||||
for scale_name, s in SCALES.items():
|
||||
W = SCREEN_PX / (LDPI * s)
|
||||
for name, keys, sp, bold, wfn, max_lines, args in slots(D):
|
||||
avail = wfn(W)
|
||||
for k, lang, t in texts(keys, args):
|
||||
n = lines_needed(t, sp, bold, avail)
|
||||
if n > max_lines:
|
||||
bad += 1
|
||||
print("DOESN'T FIT %-11s %-26s %s %-24r needs %s line(s) in %.0fdp (max %d)"
|
||||
% (scale_name, name, lang, t, "word too long:" if n == 99 else n, avail, max_lines))
|
||||
return bad
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import re
|
||||
dimens = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "res", "values", "dimens.xml")).read()
|
||||
D = {m.group(1): float(m.group(2)) for m in re.finditer(r'<dimen name="(\w+)">([\d.]+)(?:sp|dp)</dimen>', dimens)}
|
||||
n = run(D)
|
||||
print("all texts fit" if n == 0 else "%d text(s) don't fit" % n)
|
||||
sys.exit(1 if n else 0)
|
||||
@@ -54,6 +54,14 @@ PY
|
||||
python3 "$PROJ/tools/patch_bc_dalvik.py" bcsrc
|
||||
fi
|
||||
|
||||
echo "== Droid Sans (Android 2.x's font), for tools/check_fit.py"
|
||||
if [ ! -f fonts/droidsans-regular.ttf ]; then
|
||||
mkdir -p fonts dl/fonts
|
||||
curl -sSL -o dl/droid.tgz "$(curl -sS https://registry.npmjs.org/connect-fonts-droidsans/latest | python3 -c 'import json,sys;print(json.load(sys.stdin)["dist"]["tarball"])')"
|
||||
tar xzf dl/droid.tgz -C dl/fonts
|
||||
cp dl/fonts/package/fonts/latin/droidsans-regular.ttf dl/fonts/package/fonts/latin/droidsans-bold.ttf fonts/
|
||||
fi
|
||||
|
||||
echo "== signing key"
|
||||
if [ ! -f minamp.keystore ]; then
|
||||
if [ -f "$PROJ/signing/minamp.keystore" ]; then cp "$PROJ/signing/minamp.keystore" .; else
|
||||
|
||||
+19
-14
@@ -10,10 +10,10 @@ S = {
|
||||
"app_name": ("Minamp", "Minamp"),
|
||||
|
||||
# tabs / headers
|
||||
"tab_home": ("HOME", "INICIO"),
|
||||
"tab_artists": ("ARTISTS", "ARTISTAS"),
|
||||
"tab_albums": ("ALBUMS", "ÁLBUMS"),
|
||||
"tab_playlists": ("PLAYLISTS", "LISTAS"),
|
||||
"tab_home": ("Home", "Inicio"),
|
||||
"tab_artists": ("Artists", "Artistas"),
|
||||
"tab_albums": ("Albums", "Álbums"),
|
||||
"tab_playlists": ("Playlists", "Listas"),
|
||||
"playing_from": ("PLAYING FROM", "REPRODUCINDO DESDE"),
|
||||
"see_all": ("SEE ALL ›", "VER TODO ›"),
|
||||
"album_link": ("Album ›", "Álbum ›"),
|
||||
@@ -21,12 +21,12 @@ S = {
|
||||
# setup
|
||||
"tagline": ("Your Plex music, anywhere,\non a very small phone.", "A túa música de Plex, onde queiras,\nnun teléfono moi pequeno."),
|
||||
"sign_in": ("Sign in with Plex", "Iniciar sesión con Plex"),
|
||||
"connect_address": ("Connect to a server address", "Conectar a un enderezo de servidor"),
|
||||
"connect_address": ("Connect by address", "Conectar por enderezo"),
|
||||
"connection_log": ("Connection log", "Rexistro de conexión"),
|
||||
"pin_open": ("On a computer or a newer phone, open", "Nun ordenador ou nun teléfono máis novo, abre"),
|
||||
"pin_enter": ("and enter this code:", "e escribe este código:"),
|
||||
"pin_waiting": ("Waiting for you to link…", "Agardando a que vincules a conta…"),
|
||||
"pin_check_now": ("I've entered it — check now", "Xa o escribín: comprobar agora"),
|
||||
"pin_check_now": ("Check now", "Comprobar agora"),
|
||||
"cancel": ("Cancel", "Cancelar"),
|
||||
"server_address": ("Server address", "Enderezo do servidor"),
|
||||
"server_address_help": ("e.g. 192.168.1.20 or https://plex.example.com. Signing in with Plex is easier and finds remote addresses for you.",
|
||||
@@ -90,9 +90,9 @@ S = {
|
||||
|
||||
# actions
|
||||
"play": ("Play", "Reproducir"),
|
||||
"play_all": ("Play all", "Reproducir todo"),
|
||||
"play_all": ("Play all", "Reproducir"),
|
||||
"shuffle": ("Shuffle", "Aleatorio"),
|
||||
"artist_radio": ("Artist radio", "Radio do artista"),
|
||||
"artist_radio": ("Radio", "Radio"),
|
||||
"artist_radio_shuffle": ("Artist radio (shuffle)", "Radio do artista (aleatorio)"),
|
||||
"play_next": ("Play next", "Reproducir a continuación"),
|
||||
"add_to_queue": ("Add to queue", "Engadir á cola"),
|
||||
@@ -129,6 +129,11 @@ S = {
|
||||
"set_connection": ("Connection: %1$s", "Conexión: %1$s"),
|
||||
"set_log": ("Connection log & streaming test", "Rexistro de conexión e proba de reprodución"),
|
||||
"set_language": ("Language: %1$s", "Idioma: %1$s"),
|
||||
"set_size": ("Text and button size: %1$s", "Tamaño de texto e botóns: %1$s"),
|
||||
"size_title": ("Text and button size", "Tamaño de texto e botóns"),
|
||||
"size_normal": ("Normal", "Normal"),
|
||||
"size_large": ("Large", "Grande"),
|
||||
"size_xlarge": ("Extra large", "Moi grande"),
|
||||
"sign_out": ("Sign out", "Pechar sesión"),
|
||||
"quality_home_title": ("Quality at home", "Calidade na casa"),
|
||||
"quality_away_title": ("Quality away / mobile", "Calidade fóra / datos móbiles"),
|
||||
@@ -158,11 +163,11 @@ S = {
|
||||
"loved_radio": ("Favourites radio", "Radio de favoritas"),
|
||||
"loved_radio_sub": ("Your top rated", "As mellor valoradas"),
|
||||
"time_travel": ("Time travel", "Viaxe no tempo"),
|
||||
"time_travel_sub": ("Pick a decade", "Escolle unha década"),
|
||||
"time_travel_sub": ("Pick a decade", "Escolle década"),
|
||||
"random_album": ("Random album", "Álbum ao chou"),
|
||||
"random_album_sub": ("Feeling lucky", "Proba sorte"),
|
||||
"recently_added": ("Recently added", "Engadidos recentemente"),
|
||||
"recently_played": ("Recently played", "Escoitados recentemente"),
|
||||
"recently_added": ("Recently added", "Novidades"),
|
||||
"recently_played": ("Recently played", "Últimas escoitas"),
|
||||
"finding_decades": ("Finding decades…", "Buscando décadas…"),
|
||||
"no_years": ("No release years in this library", "Esta biblioteca non ten anos de publicación"),
|
||||
"surprise_me": ("Surprise me", "Sorpréndeme"),
|
||||
@@ -192,7 +197,7 @@ S = {
|
||||
"nothing_playing": ("Nothing playing", "Non se está a reproducir nada"),
|
||||
"pick_something": ("Pick something from your library", "Escolle algo da túa biblioteca"),
|
||||
"end_of_track": ("End of track", "Fin da pista"),
|
||||
"sleep": ("Sleep", "Temporizador"),
|
||||
"sleep": ("Sleep", "Durmir"),
|
||||
"sleep_timer": ("Sleep timer", "Temporizador de apagado"),
|
||||
"sleep_off": ("Off", "Desactivado"),
|
||||
"sleep_15": ("15 minutes", "15 minutos"),
|
||||
@@ -211,7 +216,7 @@ S = {
|
||||
"paused_dot": ("Paused · ", "En pausa · "),
|
||||
|
||||
# queue
|
||||
"up_next": ("Up next", "A continuación"),
|
||||
"up_next": ("Queue", "Cola"),
|
||||
"shuffle_on": ("Shuffle on", "Aleatorio activado"),
|
||||
"shuffle_off": ("Shuffle off", "Aleatorio desactivado"),
|
||||
"remove_from_queue": ("Remove from queue", "Quitar da cola"),
|
||||
@@ -220,7 +225,7 @@ S = {
|
||||
"clear_everything": ("Clear everything", "Borralo todo"),
|
||||
|
||||
# search
|
||||
"search_hint": ("Artists, albums, tracks", "Artistas, álbums, cancións"),
|
||||
"search_hint": ("Search music", "Buscar música"),
|
||||
"search_in": ("Search %1$s", "Buscar en %1$s"),
|
||||
"searching": ("Searching…", "Buscando…"),
|
||||
"nothing_found_q": ("Nothing found for “%1$s”", "Non se atopou nada para “%1$s”"),
|
||||
|
||||
Reference in new issue
Block a user