Support for multiple themes

This commit is contained in:
Adrian Ulrich 2016-05-26 20:53:05 +02:00
parent 3feadc17a0
commit 013a391cf0
26 changed files with 652 additions and 139 deletions

View File

@ -59,7 +59,7 @@ THE SOFTWARE.
android:launchMode="singleTask" />
<activity
android:name="MiniPlaybackActivity"
android:theme="@style/Dialog"
android:theme="@style/PopupDialog"
android:excludeFromRecents="true"
android:launchMode="singleInstance" />
<receiver
@ -155,7 +155,7 @@ THE SOFTWARE.
android:name="PermissionRequestActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<activity android:name="AudioPickerActivity" android:theme="@style/DialogMinWidth"
<activity android:name="AudioPickerActivity" android:theme="@style/PopupDialog"
android:excludeFromRecents="true" android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />

166
generate-themes.pl Normal file
View File

@ -0,0 +1,166 @@
#!/usr/bin/perl
use strict;
use constant THEMES_OUTDIR => './res/values-v21/';
use constant THEMES_LIST => './res/values-v21/themes-list.xml';
my $THEMES = [
{
_name => 'standard',
light => { colorAccent => '#ff3e677a', colorPrimary => '#ff37474f', colorPrimaryDark => '#ff263238'},
dark => { colorAccent => '#ff3e677a', colorPrimary => '#ff37474f', colorPrimaryDark => '#ff263238'},
},
{
_name => 'greyish',
light => { colorAccent => '#ff212121', colorPrimary => '#ff212121', colorPrimaryDark => '#ff090909'},
dark => { colorAccent => '#ffececec', colorPrimary => '#ff212121', colorPrimaryDark => '#ff090909'},
},
{
_name => 'orange',
light => { colorAccent => '#FFF57F17', colorPrimary => '#FFE65100', colorPrimaryDark => '#FFBF360C'},
dark => { colorAccent => '#FFF57F17', colorPrimary => '#FFE65100', colorPrimaryDark => '#FFBF360C'},
},
];
my $BUFF_TENTRIES = '';
my $BUFF_TVALS = '';
my $BUFF_TSTYLES = '';
my $THEME_ID = 0;
foreach my $theme_ref (@$THEMES) {
my $theme_name = $theme_ref->{_name};
my $theme_id = ($theme_name eq 'standard' ? '' : ucfirst($theme_name)."."); # standard has no prefix
my $outfile = THEMES_OUTDIR."/theme-$theme_name.xml";
my $outbuff = get_theme_xml($theme_ref, $theme_id);
open(OUT, ">", $outfile) or die "Can not write to $outfile: $!\n";
print OUT $outbuff;
close(OUT);
# use this loop to also populate the theme list output
# assumes that get_theme_xml created two themes per definition (light and dark)
foreach my $variant ('', 'Dark.') {
$BUFF_TENTRIES .= "\t\t<item>$variant".ucfirst($theme_name)."</item>\n";
$BUFF_TVALS .= "\t\t<item>".($THEME_ID)."</item>\n";
$BUFF_TSTYLES .= "\t\t<item>\@style/${theme_id}${variant}VanillaBase</item>\n";
$THEME_ID++;
}
}
open(OUT, ">", THEMES_LIST) or die "Cannot write theme list: $!\n";
print OUT << "EOLIST";
<?xml version="1.0" encoding="utf-8"?>
<!-- THIS FILE IS AUTOGENERATED BY generate-themes.pl - DO NOT TOUCH! -->
<resources>
<!-- human visible names of the themes -->
<string-array name="theme_entries">
$BUFF_TENTRIES </string-array>
<!-- the value stored in the shared preferences for each theme -->
<string-array name="theme_values">
$BUFF_TVALS </string-array>
<!-- the style id for each theme -->
<integer-array name="theme_styles">
$BUFF_TSTYLES </integer-array>
</resources>
EOLIST
close(OUT);
sub get_theme_xml {
my($this, $tid) = @_;
my $DATA = << "EOF";
<?xml version="1.0" encoding="utf-8"?>
<!--
*** THIS FILE WAS GENERATED BY 'generate-themes.pl' - DO NOT TOUCH ***
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
<style name="${tid}VanillaBase" parent="android:Theme.Material.Light.DarkActionBar">
<item name="overlay_background_color">\@color/overlay_background_light</item>
<item name="overlay_foreground_color">\@color/overlay_foreground_light</item>
<item name="float_color">\@color/material_grey_400</item>
<item name="tabs_background">$this->{light}->{colorPrimary}</item>
<item name="now_playing_marker">$this->{light}->{colorAccent}</item>
<item name="controls_normal">\@color/material_grey_600</item>
<item name="controls_active">$this->{light}->{colorAccent}</item>
<item name="android:colorAccent">$this->{light}->{colorAccent}</item>
<item name="android:colorPrimary">$this->{light}->{colorPrimary}</item>
<item name="android:colorPrimaryDark">$this->{light}->{colorPrimaryDark}</item>
</style>
<style name="${tid}Playback" parent="${tid}VanillaBase">
<item name="android:actionBarStyle">\@style/Universal.PlaybackActionBar</item>
</style>
<style name="${tid}BackActionBar" parent="${tid}VanillaBase">
<item name="android:actionBarStyle">\@style/Universal.PlaybackActionBar</item>
</style>
<style name="${tid}Library" parent="${tid}VanillaBase">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
<style name="${tid}PopupDialog" parent="android:Theme.Material.Light.Dialog.MinWidth">
<item name="controls_normal">\@color/material_grey_600</item>
<item name="controls_active">$this->{light}->{colorAccent}</item>
</style>
<!-- dark theme -->
<style name="${tid}Dark.VanillaBase" parent="android:Theme.Material">
<item name="overlay_background_color">\@color/overlay_background_dark</item>
<item name="overlay_foreground_color">\@color/overlay_foreground_dark</item>
<item name="float_color">\@color/material_grey_900</item>
<item name="tabs_background">$this->{dark}->{colorPrimary}</item>
<item name="now_playing_marker">$this->{dark}->{colorAccent}</item>
<item name="controls_normal">\@color/material_grey_600</item>
<item name="controls_active">$this->{dark}->{colorAccent}</item>
<item name="android:colorAccent">$this->{dark}->{colorAccent}</item>
<item name="android:colorPrimary">$this->{dark}->{colorPrimary}</item>
<item name="android:colorPrimaryDark">$this->{dark}->{colorPrimaryDark}</item>
</style>
<style name="${tid}Dark.Playback" parent="${tid}Dark.VanillaBase">
<item name="android:actionBarStyle">\@style/Universal.PlaybackActionBar</item>
</style>
<style name="${tid}Dark.BackActionBar" parent="${tid}Dark.VanillaBase">
<item name="android:actionBarStyle">\@style/Universal.PlaybackActionBar</item>
</style>
<style name="${tid}Dark.Library" parent="${tid}Dark.VanillaBase">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
<style name="${tid}Dark.PopupDialog" parent="android:Theme.Material.Dialog.MinWidth">
<item name="controls_normal">\@color/material_grey_600</item>
<item name="controls_active">$this->{dark}->{colorAccent}</item>
</style>
</resources>
EOF
return $DATA
}

View File

@ -23,7 +23,7 @@
<ch.blinkenlights.android.vanilla.BottomBarControls
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/tabs_background"
android:background="?tabs_background"
android:elevation="8dp"
android:orientation="vertical"
android:layout_width="fill_parent"

View File

@ -32,7 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
android:visibility="gone"
android:layout_width="@dimen/pmark_size"
android:layout_height="@dimen/row_normal_height"
android:background="@color/now_playing_marker" />
android:background="?now_playing_marker" />
<ch.blinkenlights.android.vanilla.LazyCoverView
android:id="@+id/cover"

View File

@ -33,7 +33,7 @@ THE SOFTWARE.
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="4dp"
android:background="@color/tabs_background" />
android:background="?tabs_background" />
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="fill_parent"

View File

@ -14,15 +14,7 @@
<color name="vanillaPrimaryDark">#ff263238</color>
<color name="vanillaAccent">#ff3e677a</color>
<!-- now-playing screen buttons tint -->
<color name="controls_active">@color/vanillaAccent</color>
<color name="controls_normal">@color/material_grey_600</color>
<!-- showqueue info -->
<color name="now_playing_marker">@color/vanillaAccent</color>
<!-- library tabs -->
<color name="tabs_background">@color/vanillaPrimary</color>
<color name="tabs_active_indicator">@android:color/background_light</color>
<!-- themed overlay colors for full playback activity -->

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
*** THIS FILE WAS GENERATED BY 'generate-themes.pl' - DO NOT TOUCH ***
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
<style name="Greyish.VanillaBase" parent="android:Theme.Material.Light.DarkActionBar">
<item name="overlay_background_color">@color/overlay_background_light</item>
<item name="overlay_foreground_color">@color/overlay_foreground_light</item>
<item name="float_color">@color/material_grey_400</item>
<item name="tabs_background">#ff212121</item>
<item name="now_playing_marker">#ff212121</item>
<item name="controls_normal">@color/material_grey_600</item>
<item name="controls_active">#ff212121</item>
<item name="android:colorAccent">#ff212121</item>
<item name="android:colorPrimary">#ff212121</item>
<item name="android:colorPrimaryDark">#ff090909</item>
</style>
<style name="Greyish.Playback" parent="Greyish.VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
</style>
<style name="Greyish.BackActionBar" parent="Greyish.VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
</style>
<style name="Greyish.Library" parent="Greyish.VanillaBase">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
<style name="Greyish.PopupDialog" parent="android:Theme.Material.Light.Dialog.MinWidth">
<item name="controls_normal">@color/material_grey_600</item>
<item name="controls_active">#ff212121</item>
</style>
<!-- dark theme -->
<style name="Greyish.Dark.VanillaBase" parent="android:Theme.Material">
<item name="overlay_background_color">@color/overlay_background_dark</item>
<item name="overlay_foreground_color">@color/overlay_foreground_dark</item>
<item name="float_color">@color/material_grey_900</item>
<item name="tabs_background">#ff212121</item>
<item name="now_playing_marker">#ffececec</item>
<item name="controls_normal">@color/material_grey_600</item>
<item name="controls_active">#ffececec</item>
<item name="android:colorAccent">#ffececec</item>
<item name="android:colorPrimary">#ff212121</item>
<item name="android:colorPrimaryDark">#ff090909</item>
</style>
<style name="Greyish.Dark.Playback" parent="Greyish.Dark.VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
</style>
<style name="Greyish.Dark.BackActionBar" parent="Greyish.Dark.VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
</style>
<style name="Greyish.Dark.Library" parent="Greyish.Dark.VanillaBase">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
<style name="Greyish.Dark.PopupDialog" parent="android:Theme.Material.Dialog.MinWidth">
<item name="controls_normal">@color/material_grey_600</item>
<item name="controls_active">#ffececec</item>
</style>
</resources>

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
*** THIS FILE WAS GENERATED BY 'generate-themes.pl' - DO NOT TOUCH ***
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
<style name="Orange.VanillaBase" parent="android:Theme.Material.Light.DarkActionBar">
<item name="overlay_background_color">@color/overlay_background_light</item>
<item name="overlay_foreground_color">@color/overlay_foreground_light</item>
<item name="float_color">@color/material_grey_400</item>
<item name="tabs_background">#FFE65100</item>
<item name="now_playing_marker">#FFF57F17</item>
<item name="controls_normal">@color/material_grey_600</item>
<item name="controls_active">#FFF57F17</item>
<item name="android:colorAccent">#FFF57F17</item>
<item name="android:colorPrimary">#FFE65100</item>
<item name="android:colorPrimaryDark">#FFBF360C</item>
</style>
<style name="Orange.Playback" parent="Orange.VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
</style>
<style name="Orange.BackActionBar" parent="Orange.VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
</style>
<style name="Orange.Library" parent="Orange.VanillaBase">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
<style name="Orange.PopupDialog" parent="android:Theme.Material.Light.Dialog.MinWidth">
<item name="controls_normal">@color/material_grey_600</item>
<item name="controls_active">#FFF57F17</item>
</style>
<!-- dark theme -->
<style name="Orange.Dark.VanillaBase" parent="android:Theme.Material">
<item name="overlay_background_color">@color/overlay_background_dark</item>
<item name="overlay_foreground_color">@color/overlay_foreground_dark</item>
<item name="float_color">@color/material_grey_900</item>
<item name="tabs_background">#FFE65100</item>
<item name="now_playing_marker">#FFF57F17</item>
<item name="controls_normal">@color/material_grey_600</item>
<item name="controls_active">#FFF57F17</item>
<item name="android:colorAccent">#FFF57F17</item>
<item name="android:colorPrimary">#FFE65100</item>
<item name="android:colorPrimaryDark">#FFBF360C</item>
</style>
<style name="Orange.Dark.Playback" parent="Orange.Dark.VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
</style>
<style name="Orange.Dark.BackActionBar" parent="Orange.Dark.VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
</style>
<style name="Orange.Dark.Library" parent="Orange.Dark.VanillaBase">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
<style name="Orange.Dark.PopupDialog" parent="android:Theme.Material.Dialog.MinWidth">
<item name="controls_normal">@color/material_grey_600</item>
<item name="controls_active">#FFF57F17</item>
</style>
</resources>

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
*** THIS FILE WAS GENERATED BY 'generate-themes.pl' - DO NOT TOUCH ***
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
<style name="VanillaBase" parent="android:Theme.Material.Light.DarkActionBar">
<item name="overlay_background_color">@color/overlay_background_light</item>
<item name="overlay_foreground_color">@color/overlay_foreground_light</item>
<item name="float_color">@color/material_grey_400</item>
<item name="tabs_background">#ff37474f</item>
<item name="now_playing_marker">#ff3e677a</item>
<item name="controls_normal">@color/material_grey_600</item>
<item name="controls_active">#ff3e677a</item>
<item name="android:colorAccent">#ff3e677a</item>
<item name="android:colorPrimary">#ff37474f</item>
<item name="android:colorPrimaryDark">#ff263238</item>
</style>
<style name="Playback" parent="VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
</style>
<style name="BackActionBar" parent="VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
</style>
<style name="Library" parent="VanillaBase">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
<style name="PopupDialog" parent="android:Theme.Material.Light.Dialog.MinWidth">
<item name="controls_normal">@color/material_grey_600</item>
<item name="controls_active">#ff3e677a</item>
</style>
<!-- dark theme -->
<style name="Dark.VanillaBase" parent="android:Theme.Material">
<item name="overlay_background_color">@color/overlay_background_dark</item>
<item name="overlay_foreground_color">@color/overlay_foreground_dark</item>
<item name="float_color">@color/material_grey_900</item>
<item name="tabs_background">#ff37474f</item>
<item name="now_playing_marker">#ff3e677a</item>
<item name="controls_normal">@color/material_grey_600</item>
<item name="controls_active">#ff3e677a</item>
<item name="android:colorAccent">#ff3e677a</item>
<item name="android:colorPrimary">#ff37474f</item>
<item name="android:colorPrimaryDark">#ff263238</item>
</style>
<style name="Dark.Playback" parent="Dark.VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
</style>
<style name="Dark.BackActionBar" parent="Dark.VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
</style>
<style name="Dark.Library" parent="Dark.VanillaBase">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
<style name="Dark.PopupDialog" parent="android:Theme.Material.Dialog.MinWidth">
<item name="controls_normal">@color/material_grey_600</item>
<item name="controls_active">#ff3e677a</item>
</style>
</resources>

View File

@ -17,62 +17,10 @@ Copyright (C) 2015 Adrian Ulrich <adrian@blinkenlights.ch>
-->
<resources>
<!-- styles -->
<style name="Dialog" parent="android:Theme.Material.Light.Dialog" />
<style name="DialogMinWidth" parent="android:Theme.Material.Light.Dialog.MinWidth" />
<style name="VanillaBase" parent="android:Theme.Material.Light.DarkActionBar">
<item name="overlay_background_color">@color/overlay_background_light</item>
<item name="overlay_foreground_color">@color/overlay_foreground_light</item>
<item name="float_color">@color/material_grey_400</item>
<item name="android:colorAccent">@color/vanillaAccent</item>
<item name="android:colorPrimary">@color/vanillaPrimary</item>
<item name="android:colorPrimaryDark">@color/vanillaPrimaryDark</item>
</style>
<style name="Playback" parent="VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
</style>
<style name="BackActionBar" parent="VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
</style>
<style name="Library" parent="VanillaBase">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
<!-- universal styles -->
<style name="Universal.PlaybackActionBar" parent="android:Widget.Material.ActionBar">
<item name="android:displayOptions">showTitle|homeAsUp</item>
<item name="android:background">@color/vanillaPrimary</item>
<item name="android:background">?tabs_background</item>
</style>
<!-- dark theme -->
<style name="Dark.VanillaBase" parent="android:Theme.Material">
<item name="overlay_background_color">@color/overlay_background_dark</item>
<item name="overlay_foreground_color">@color/overlay_foreground_dark</item>
<item name="float_color">@color/material_grey_900</item>
<item name="android:colorAccent">@color/vanillaAccent</item>
<item name="android:colorPrimary">@color/vanillaPrimary</item>
<item name="android:colorPrimaryDark">@color/vanillaPrimaryDark</item>
</style>
<style name="Dark.Playback" parent="Dark.VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
</style>
<style name="Dark.BackActionBar" parent="Dark.VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
</style>
<style name="Dark.Library" parent="Dark.VanillaBase">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- THIS FILE IS AUTOGENERATED BY generate-themes.pl - DO NOT TOUCH! -->
<resources>
<!-- human visible names of the themes -->
<string-array name="theme_entries">
<item>Standard</item>
<item>Dark.Standard</item>
<item>Greyish</item>
<item>Dark.Greyish</item>
<item>Orange</item>
<item>Dark.Orange</item>
</string-array>
<!-- the value stored in the shared preferences for each theme -->
<string-array name="theme_values">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
</string-array>
<!-- the style id for each theme -->
<integer-array name="theme_styles">
<item>@style/VanillaBase</item>
<item>@style/Dark.VanillaBase</item>
<item>@style/Greyish.VanillaBase</item>
<item>@style/Greyish.Dark.VanillaBase</item>
<item>@style/Orange.VanillaBase</item>
<item>@style/Orange.Dark.VanillaBase</item>
</integer-array>
</resources>

View File

@ -2,4 +2,8 @@
<attr name="overlay_background_color" format="color" />
<attr name="overlay_foreground_color" format="color" />
<attr name="float_color" format="color" />
<attr name="tabs_background" format="color" />
<attr name="now_playing_marker" format="color" />
<attr name="controls_normal" format="color" />
<attr name="controls_active" format="color" />
</resources>

View File

@ -1,11 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- now-playing screen buttons tint -->
<color name="controls_active">@android:color/holo_blue_dark</color>
<color name="controls_normal">#fff5f5f5</color>
<!-- showqueue info -->
<color name="now_playing_marker">@android:color/holo_blue_dark</color>
<!-- library tabs -->
<color name="tabs_background">#ff1e1e1e</color>
<color name="tabs_active_indicator">@android:color/holo_blue_dark</color>
</resources>

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2010 Christopher Eby <kreed@kreed.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<resources>
<style name="VanillaBase" parent="android:Theme.Holo">
<item name="overlay_background_color">#a000</item>
<!-- color to use in full_playback text, set to bright_foreground_disabled_holo_light //-->
<item name="overlay_foreground_color">#ffb2b2b2</item>
<item name="float_color">#f222</item>
<item name="tabs_background">#ff1e1e1e</item>
<item name="now_playing_marker">@android:color/holo_blue_dark</item>
<item name="controls_normal">#fff5f5f5</item>
<item name="controls_active">@android:color/holo_blue_dark</item>
<item name="android:scrollbarStyle">outsideInset</item>
</style>
<style name="Playback" parent="VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
<item name="android:windowBackground">@android:color/black</item>
</style>
<style name="BackActionBar" parent="VanillaBase">
<item name="android:actionBarStyle">@style/Universal.PlaybackActionBar</item>
</style>
<style name="Library" parent="VanillaBase">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
<style name="PopupDialog" parent="android:Theme.Holo.Dialog.MinWidth" />
</resources>

View File

@ -22,33 +22,7 @@ THE SOFTWARE.
-->
<resources>
<!-- styles -->
<style name="Dialog" parent="android:Theme.Holo.Dialog" />
<style name="DialogMinWidth" parent="android:Theme.Holo.Dialog.MinWidth" />
<style name="AlertDialogItem">
<item name="android:textColor">?android:textColorAlertDialogListItem</item>
</style>
<style name="VanillaBase" parent="android:Theme.Holo">
<item name="overlay_background_color">#a000</item>
<!-- color to use in full_playback text, set to bright_foreground_disabled_holo_light //-->
<item name="overlay_foreground_color">#ffb2b2b2</item>
<item name="float_color">#f222</item>
<item name="android:scrollbarStyle">outsideInset</item>
</style>
<style name="Playback" parent="VanillaBase">
<item name="android:actionBarStyle">@style/PlaybackActionBar</item>
<item name="android:windowBackground">@android:color/black</item>
</style>
<style name="BackActionBar" parent="VanillaBase">
<item name="android:actionBarStyle">@style/PlaybackActionBar</item>
</style>
<style name="PlaybackActionBar" parent="android:Widget.Holo.ActionBar">
<style name="Universal.PlaybackActionBar" parent="android:Widget.Holo.ActionBar">
<item name="android:displayOptions">showTitle|homeAsUp</item>
</style>
<style name="Library" parent="VanillaBase">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>

View File

@ -207,8 +207,7 @@ THE SOFTWARE.
<string name="shake_threshold_title">Shake force threshold</string>
<string name="misc_features">Miscellaneous features</string>
<string name="use_dark_theme_title">Use dark theme</string>
<string name="use_dark_theme_summary">Enables the dark material theme</string>
<string name="theme">Theme</string>
<string name="disable_lockscreen_title">Disable lockscreen</string>
<string name="disable_lockscreen_summary">Prevent the lockscreen from activating when in the library or playback screen</string>
<string name="use_idle_timeout_title">Enable idle timeout</string>

View File

@ -42,6 +42,9 @@ THE SOFTWARE.
<header
android:fragment="ch.blinkenlights.android.vanilla.PreferencesActivity$MiscFragment"
android:title="@string/misc_features" />
<header
android:fragment="ch.blinkenlights.android.vanilla.PreferencesTheme"
android:title="@string/theme" />
<header
android:fragment="ch.blinkenlights.android.vanilla.PreferencesActivity$AboutFragment"
android:title="@string/about" />

View File

@ -28,11 +28,6 @@ THE SOFTWARE.
android:title="@string/playback_on_startup_title"
android:summary="@string/playback_on_startup_summary"
android:defaultValue="false" />
<CheckBoxPreference
android:key="use_dark_theme"
android:title="@string/use_dark_theme_title"
android:summary="@string/use_dark_theme_summary"
android:defaultValue="false" />
<ch.blinkenlights.android.vanilla.ListPreferenceSummary
android:key="display_mode"
android:title="@string/display_mode_title"

View File

@ -37,6 +37,7 @@ public class MiniPlaybackActivity extends PlaybackActivity {
@Override
public void onCreate(Bundle state)
{
ThemeHelper.setTheme(this, R.style.PopupDialog);
super.onCreate(state);
requestWindowFeature(Window.FEATURE_NO_TITLE);

View File

@ -884,7 +884,7 @@ public final class PlaybackService extends Service
mReadaheadEnabled = settings.getBoolean(PrefKeys.ENABLE_READAHEAD, PrefDefaults.ENABLE_READAHEAD);
} else if (PrefKeys.AUTOPLAYLIST_PLAYCOUNTS.equals(key)) {
mAutoPlPlaycounts = settings.getInt(PrefKeys.AUTOPLAYLIST_PLAYCOUNTS, PrefDefaults.AUTOPLAYLIST_PLAYCOUNTS);
} else if (PrefKeys.USE_DARK_THEME.equals(key) || PrefKeys.DISPLAY_MODE.equals(key)) {
} else if (PrefKeys.SELECTED_THEME.equals(key) || PrefKeys.DISPLAY_MODE.equals(key)) {
// Theme changed: trigger a restart of all registered activites
ArrayList<TimelineCallback> list = sCallbacks;
for (int i = list.size(); --i != -1; )

View File

@ -64,7 +64,7 @@ public class PrefDefaults {
public static final int REPLAYGAIN_BUMP = 75; // seek bar is 150 -> 75 == middle == 0
public static final int REPLAYGAIN_UNTAGGED_DEBUMP = 150; // seek bar is 150 -> == 0
public static final boolean ENABLE_READAHEAD = false;
public static final boolean USE_DARK_THEME = false;
public static final String SELECTED_THEME = "0";
public static final String FILESYSTEM_BROWSE_START = "";
public static final int VOLUME_DURING_DUCKING = 50;
public static final int AUTOPLAYLIST_PLAYCOUNTS = 0;

View File

@ -65,7 +65,7 @@ public class PrefKeys {
public static final String REPLAYGAIN_BUMP = "replaygain_bump";
public static final String REPLAYGAIN_UNTAGGED_DEBUMP = "replaygain_untagged_debump";
public static final String ENABLE_READAHEAD = "enable_readahead";
public static final String USE_DARK_THEME = "use_dark_theme";
public static final String SELECTED_THEME = "selected_theme";
public static final String FILESYSTEM_BROWSE_START = "filesystem_browse_start";
public static final String VOLUME_DURING_DUCKING = "volume_during_ducking";
public static final String AUTOPLAYLIST_PLAYCOUNTS = "playcounts_autoplaylist";

View File

@ -27,6 +27,7 @@ import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
@ -52,7 +53,9 @@ import java.util.List;
/**
* The preferences activity in which one can change application preferences.
*/
public class PreferencesActivity extends PreferenceActivity {
public class PreferencesActivity extends PreferenceActivity
implements SharedPreferences.OnSharedPreferenceChangeListener
{
/**
* The package name of our external helper app
@ -68,6 +71,13 @@ public class PreferencesActivity extends PreferenceActivity {
{
ThemeHelper.setTheme(this, R.style.BackActionBar);
super.onCreate(savedInstanceState);
PlaybackService.getSettings(this).registerOnSharedPreferenceChangeListener(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
PlaybackService.getSettings(this).unregisterOnSharedPreferenceChangeListener(this);
}
@Override
@ -87,6 +97,15 @@ public class PreferencesActivity extends PreferenceActivity {
}
}
@Override
public void onSharedPreferenceChanged (SharedPreferences sharedPreferences, String key) {
if (PrefKeys.SELECTED_THEME.equals(key)) {
// this gets called by all preference instances: we force them to redraw
// themselfes if the theme changed
recreate();
}
}
public static class AudioFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState)
@ -106,13 +125,13 @@ public class PreferencesActivity extends PreferenceActivity {
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preference_replaygain);
cbTrackReplayGain = (CheckBoxPreference)findPreference(PrefKeys.ENABLE_TRACK_REPLAYGAIN);
cbAlbumReplayGain = (CheckBoxPreference)findPreference(PrefKeys.ENABLE_ALBUM_REPLAYGAIN);
sbGainBump = (SeekBarPreference)findPreference(PrefKeys.REPLAYGAIN_BUMP);
sbUntaggedDebump = (SeekBarPreference)findPreference(PrefKeys.REPLAYGAIN_UNTAGGED_DEBUMP);
Preference.OnPreferenceClickListener pcListener = new Preference.OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
updateConfigWidgets();
@ -164,14 +183,6 @@ public class PreferencesActivity extends PreferenceActivity {
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preference_playback);
// Hide the dark theme preference if this device
// does not support multiple themes
PreferenceScreen screen = getPreferenceScreen();
CheckBoxPreference dark_theme_pref = (CheckBoxPreference)findPreference("use_dark_theme");
if (ThemeHelper.usesHoloTheme()) // not available on 4.x devices
screen.removePreference(dark_theme_pref);
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2016 Adrian Ulrich <adrian@blinkenlights.ch>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ch.blinkenlights.android.vanilla;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
import android.util.Log;
public class PreferencesTheme extends PreferenceFragment
implements Preference.OnPreferenceClickListener
{
private Context mContext;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = getActivity();
// Themes are 'pre-compiled' in themes-list: get all values
// and append them to our newly created PreferenceScreen
PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(mContext);
final String[] entries = getResources().getStringArray(R.array.theme_entries);
final String[] values = getResources().getStringArray(R.array.theme_values);
for (int i = 0; i < entries.length; i++) {
final Preference pref = new Preference(mContext);
pref.setPersistent(false);
pref.setOnPreferenceClickListener(this);
pref.setTitle(entries[i]);
pref.setKey(values[i]); // that's actually our value
pref.setIcon(R.drawable.icon);
screen.addPreference(pref);
}
setPreferenceScreen(screen);
}
@Override
public boolean onPreferenceClick(Preference pref) {
SharedPreferences.Editor editor = PlaybackService.getSettings(mContext).edit();
editor.putString(PrefKeys.SELECTED_THEME, pref.getKey());
editor.apply();
return true;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 Adrian Ulrich <adrian@blinkenlights.ch>
* Copyright (C) 2015-2016 Adrian Ulrich <adrian@blinkenlights.ch>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -18,6 +18,7 @@
package ch.blinkenlights.android.vanilla;
import android.content.Context;
import android.content.res.TypedArray;
import android.content.SharedPreferences;
import android.os.Build;
@ -30,19 +31,26 @@ public class ThemeHelper {
*/
final public static int setTheme(Context context, int theme)
{
if (usesDarkTheme(context)) {
if(usesHoloTheme() == false) {
TypedArray ar = context.getResources().obtainTypedArray(R.array.theme_styles);
int themeBase = ar.getResourceId(getSelectedTheme(context), R.style.VanillaBase);
ar.recycle();
switch (theme) {
case R.style.Playback:
theme = R.style.Dark_Playback;
theme = themeBase + (R.style.Playback - R.style.VanillaBase);
break;
case R.style.Library:
theme = R.style.Dark_Library;
theme = themeBase + (R.style.Library - R.style.VanillaBase);
break;
case R.style.BackActionBar:
theme = R.style.Dark_BackActionBar;
theme = themeBase + (R.style.BackActionBar - R.style.VanillaBase);
break;
case R.style.PopupDialog:
theme = themeBase + (R.style.PopupDialog - R.style.VanillaBase);
break;
default:
break;
throw new IllegalArgumentException("setTheme() called with unknown theme!");
}
}
context.setTheme(theme);
@ -74,12 +82,22 @@ public class ThemeHelper {
{
boolean useDark = false;
if(usesHoloTheme() == false) {
SharedPreferences settings = PlaybackService.getSettings(context);
useDark = settings.getBoolean(PrefKeys.USE_DARK_THEME, PrefDefaults.USE_DARK_THEME);
useDark = (getSelectedTheme(context) % 2 != 0); // odd values are always dark
}
return useDark;
}
/**
* Returns the user-selected theme id from the shared peferences provider
*
* @param context the context to use
* @return integer of the selected theme
*/
final private static int getSelectedTheme(Context context) {
SharedPreferences settings = PlaybackService.getSettings(context);
return Integer.parseInt(settings.getString(PrefKeys.SELECTED_THEME, PrefDefaults.SELECTED_THEME));
}
/**
* Returns TRUE if this device uses the HOLO (android 4) theme
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 Adrian Ulrich <adrian@blinkenlights.ch>
* Copyright (C) 2015-2016 Adrian Ulrich <adrian@blinkenlights.ch>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,7 +19,9 @@
package ch.blinkenlights.android.vanilla;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ImageButton;
import android.graphics.Color;
import android.graphics.ColorFilter;
@ -27,22 +29,22 @@ import android.graphics.ColorFilter;
public class VanillaImageButton extends ImageButton {
private Context mContext;
private static int mNormalTint;
private static int mActiveTint;
public VanillaImageButton(Context context) {
super(context);
mContext = context;
updateImageTint(-1);
this(context, null);
}
public VanillaImageButton(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
updateImageTint(-1);
this(context, attrs, 0);
}
public VanillaImageButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
mNormalTint = fetchAttrColor(R.attr.controls_normal);
mActiveTint = fetchAttrColor(R.attr.controls_active);
updateImageTint(-1);
}
@ -52,9 +54,8 @@ public class VanillaImageButton extends ImageButton {
this.updateImageTint(resId);
}
private void updateImageTint(int resHint) {
int filterColor = R.color.controls_normal;
int filterColor = mNormalTint;
switch (resHint) {
case R.drawable.repeat_active:
@ -63,10 +64,18 @@ public class VanillaImageButton extends ImageButton {
case R.drawable.shuffle_active:
case R.drawable.shuffle_album_active:
case R.drawable.random_active:
filterColor = R.color.controls_active;
filterColor = mActiveTint;
}
this.setColorFilter(mContext.getResources().getColor(filterColor));
this.setColorFilter(filterColor);
}
private int fetchAttrColor(int attr) {
TypedValue typedValue = new TypedValue();
TypedArray a = mContext.obtainStyledAttributes(typedValue.data, new int[] { attr });
int color = a.getColor(0, 0);
a.recycle();
return color;
}
}