Make remote bottom bar configurable (#355)

* Make remote bottom bar configurable
* Added new translations
* Added icons
* Moved preference to remote section
This commit is contained in:
tomerf 2017-03-06 21:58:31 +02:00 committed by Synced Synapse
parent d1b1827a5f
commit b80e3e0e7a
16 changed files with 257 additions and 18 deletions

View File

@ -128,6 +128,11 @@ public class Settings {
public static final String KEY_PREF_CURRENT_HOST_ID = "current_host_id";
public static final int DEFAULT_PREF_CURRENT_HOST_ID = -1;
public static final String KEY_PREF_REMOTE_BAR_ITEMS = "pref_remote_bar_items";
public static String getRemoteBarItemsPrefKey(int hostId) {
return Settings.KEY_PREF_REMOTE_BAR_ITEMS + hostId;
}
public static final String KEY_PREF_NAV_DRAWER_ITEMS = "pref_nav_drawer_items";
public static String getNavDrawerItemsPrefKey(int hostId) {
return Settings.KEY_PREF_NAV_DRAWER_ITEMS + hostId;

View File

@ -155,6 +155,10 @@ public class GUI {
* For use in params, to go directly to TV shows
*/
public final static String PARAM_TV_SHOWS_TITLES = "TvShowTitles";
/**
* For use in params, to go to root screen
*/
public final static String PARAM_ROOT = "Root";
/**
* Activates a window in XBMC. See class constants to check which windows are allowed.

View File

@ -139,13 +139,17 @@ public class AddHostFragmentFinish extends Fragment {
boolean isEnabled = result.asBoolean(false);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
Set<String> shownItems = new HashSet<>(Arrays.asList(
Set<String> barItems = new HashSet<>(Arrays.asList(
context.getResources()
.getStringArray(R.array.default_values_remote_bar_items)));
Set<String> navItems = new HashSet<>(Arrays.asList(
context.getResources()
.getStringArray(R.array.entry_values_nav_drawer_items)));
if (!isEnabled)
shownItems.remove(String.valueOf(NavigationDrawerFragment.ACTIVITY_PVR));
navItems.remove(String.valueOf(NavigationDrawerFragment.ACTIVITY_PVR));
sp.edit()
.putStringSet(Settings.getNavDrawerItemsPrefKey(hostId), shownItems)
.putStringSet(Settings.getRemoteBarItemsPrefKey(hostId), barItems)
.putStringSet(Settings.getNavDrawerItemsPrefKey(hostId), navItems)
.apply();
}

View File

@ -25,6 +25,7 @@ import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@ -39,6 +40,7 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import org.xbmc.kore.R;
import org.xbmc.kore.Settings;
import org.xbmc.kore.eventclient.ButtonCodes;
import org.xbmc.kore.eventclient.EventServerConnection;
import org.xbmc.kore.eventclient.Packet;
@ -59,9 +61,14 @@ import org.xbmc.kore.utils.RepeatListener;
import org.xbmc.kore.utils.UIUtils;
import org.xbmc.kore.utils.Utils;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import butterknife.ButterKnife;
import butterknife.InjectView;
import butterknife.OnClick;
import butterknife.Optional;
/**
* Remote view
@ -107,11 +114,17 @@ public class RemoteFragment extends Fragment
/**
* Buttons
*/
@InjectView(R.id.home) ImageButton homeButton;
@InjectView(R.id.movies) ImageButton moviesButton;
@InjectView(R.id.tv_shows) ImageButton tvShowsButton;
@InjectView(R.id.music) ImageButton musicButton;
@InjectView(R.id.pictures) ImageButton picturesButton;
@Optional @InjectView(R.id.home) ImageButton homeButton;
@Optional @InjectView(R.id.movies) ImageButton moviesButton;
@Optional @InjectView(R.id.tv_shows) ImageButton tvShowsButton;
@Optional @InjectView(R.id.music) ImageButton musicButton;
@Optional @InjectView(R.id.pvr) ImageButton pvrButton;
@Optional @InjectView(R.id.pictures) ImageButton picturesButton;
@Optional @InjectView(R.id.videos) ImageButton videosButton;
//@Optional @InjectView(R.id.favourites) ImageButton favouritesButton;
@Optional @InjectView(R.id.addons) ImageButton addonsButton;
@Optional @InjectView(R.id.weather) ImageButton weatherButton;
@Optional @InjectView(R.id.system) ImageButton systemButton;
@InjectView(R.id.select) ImageView selectButton;
@InjectView(R.id.left) ImageView leftButton;
@ -227,6 +240,19 @@ public class RemoteFragment extends Fragment
skipPreviousIcon = styledAttributes.getResourceId(styledAttributes.getIndex(3), R.drawable.ic_skip_previous_white_24dp);
styledAttributes.recycle();
Set<String> shownItems = PreferenceManager
.getDefaultSharedPreferences(getActivity())
.getStringSet(Settings.getRemoteBarItemsPrefKey(hostInfo.getId()),
new HashSet<>(Arrays.asList(getResources().getStringArray(R.array.default_values_remote_bar_items))));
ImageButton[] buttons = {
homeButton, moviesButton, tvShowsButton, musicButton, pvrButton, picturesButton,
videosButton, addonsButton, weatherButton, systemButton
};
for (int i = 0; i < buttons.length; i++) {
if (buttons[i] != null)
buttons[i].setVisibility(shownItems.contains(String.valueOf(i)) ? View.VISIBLE : View.GONE);
}
// // Pad main content view to account for bottom system bar
// UIUtils.setPaddingForSystemBars(getActivity(), root, false, false, true);
@ -274,7 +300,6 @@ public class RemoteFragment extends Fragment
}
}
@Override
public void onActivityCreated (Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
@ -404,38 +429,85 @@ public class RemoteFragment extends Fragment
private ApiCallback<String> defaultActionCallback = ApiMethod.getDefaultActionCallback();
/**
* Callbacks for boottoom button bar
* Callbacks for bottom button bar
*/
@Optional
@OnClick(R.id.home)
public void onHomeClicked(View v) {
GUI.ActivateWindow action = new GUI.ActivateWindow(GUI.ActivateWindow.HOME);
action.execute(hostManager.getConnection(), defaultActionCallback, callbackHandler);
}
@Optional
@OnClick(R.id.movies)
public void onMoviedClicked(View v) {
GUI.ActivateWindow action = new GUI.ActivateWindow(GUI.ActivateWindow.VIDEOS, GUI.ActivateWindow.PARAM_MOVIE_TITLES);
action.execute(hostManager.getConnection(), defaultActionCallback, callbackHandler);
}
@Optional
@OnClick(R.id.tv_shows)
public void onTvShowsClicked(View v) {
GUI.ActivateWindow action = new GUI.ActivateWindow(GUI.ActivateWindow.VIDEOS, GUI.ActivateWindow.PARAM_TV_SHOWS_TITLES);
action.execute(hostManager.getConnection(), defaultActionCallback, callbackHandler);
}
@Optional
@OnClick(R.id.music)
public void onMusicClicked(View v) {
GUI.ActivateWindow action = new GUI.ActivateWindow(GUI.ActivateWindow.MUSICLIBRARY);
GUI.ActivateWindow action = new GUI.ActivateWindow(GUI.ActivateWindow.MUSIC, GUI.ActivateWindow.PARAM_ROOT);
action.execute(hostManager.getConnection(), defaultActionCallback, callbackHandler);
}
@Optional
@OnClick(R.id.pvr)
public void onRadioClicked(View v) {
GUI.ActivateWindow action = new GUI.ActivateWindow(GUI.ActivateWindow.PVR);
action.execute(hostManager.getConnection(), defaultActionCallback, callbackHandler);
}
@Optional
@OnClick(R.id.pictures)
public void onPicturesClicked(View v) {
GUI.ActivateWindow action = new GUI.ActivateWindow(GUI.ActivateWindow.PICTURES);
action.execute(hostManager.getConnection(), defaultActionCallback, callbackHandler);
}
@Optional
@OnClick(R.id.videos)
public void onVideosClicked(View v) {
GUI.ActivateWindow action = new GUI.ActivateWindow(GUI.ActivateWindow.VIDEOS, GUI.ActivateWindow.PARAM_ROOT);
action.execute(hostManager.getConnection(), defaultActionCallback, callbackHandler);
}
/*@Optional
@OnClick(R.id.favourites)
public void onFavouritesClicked(View v) {
GUI.ActivateWindow action = new GUI.ActivateWindow(GUI.ActivateWindow.FAVOURITES);
action.execute(hostManager.getConnection(), defaultActionCallback, callbackHandler);
}*/
@Optional
@OnClick(R.id.addons)
public void onAddonsClicked(View v) {
GUI.ActivateWindow action = new GUI.ActivateWindow(GUI.ActivateWindow.ADDONBROWSER);
action.execute(hostManager.getConnection(), defaultActionCallback, callbackHandler);
}
@Optional
@OnClick(R.id.weather)
public void onWeatherClicked(View v) {
GUI.ActivateWindow action = new GUI.ActivateWindow(GUI.ActivateWindow.WEATHER);
action.execute(hostManager.getConnection(), defaultActionCallback, callbackHandler);
}
@Optional
@OnClick(R.id.system)
public void onSystemClicked(View v) {
GUI.ActivateWindow action = new GUI.ActivateWindow(GUI.ActivateWindow.SETTINGS);
action.execute(hostManager.getConnection(), defaultActionCallback, callbackHandler);
}
/**
* Calllbacks for media control buttons
*/

View File

@ -56,17 +56,19 @@ public class SettingsFragment extends PreferenceFragmentCompat
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
// Get the preference for side menu itens and change its Id to include
// Get the preference for side menu items and change its Id to include
// the current host
Preference sideMenuItems = findPreference(Settings.KEY_PREF_NAV_DRAWER_ITEMS);
Preference remoteBarItems = findPreference(Settings.KEY_PREF_REMOTE_BAR_ITEMS);
hostId = HostManager.getInstance(getActivity()).getHostInfo().getId();
sideMenuItems.setKey(Settings.getNavDrawerItemsPrefKey(hostId));
remoteBarItems.setKey(Settings.getRemoteBarItemsPrefKey(hostId));
// HACK: After changing the key dinamically like above, we need to force the preference
// HACK: After changing the key dynamically like above, we need to force the preference
// to read its value. This can be done by calling onSetInitialValue, which is protected,
// so, instead of subclassing MultiSelectListPreference and make it public, this little
// hack changes its access mode.
// Furthermore, only do this is nothing is saved yet on the shared preferences,
// Furthermore, only do this if nothing is saved yet on the shared preferences,
// otherwise the defaults won't be applied
if (getPreferenceManager().getSharedPreferences().getStringSet(Settings.getNavDrawerItemsPrefKey(hostId), null) != null) {
Class iterClass = sideMenuItems.getClass();
@ -78,6 +80,16 @@ public class SettingsFragment extends PreferenceFragmentCompat
} catch (Exception e) {
}
}
if (getPreferenceManager().getSharedPreferences().getStringSet(Settings.getRemoteBarItemsPrefKey(hostId), null) != null) {
Class iterClass = remoteBarItems.getClass();
try {
@SuppressWarnings("unchecked")
Method m = iterClass.getDeclaredMethod("onSetInitialValue", boolean.class, Object.class);
m.setAccessible(true);
m.invoke(remoteBarItems, true, null);
} catch (Exception e) {
}
}
// Check permission for phone state and set preference accordingly
if (!hasPhonePermission()) {
@ -110,15 +122,16 @@ public class SettingsFragment extends PreferenceFragmentCompat
// Update summaries
setupPreferences();
if (key.equals(Settings.KEY_PREF_THEME) || key.equals(Settings.getNavDrawerItemsPrefKey(hostId))) {
if (key.equals(Settings.KEY_PREF_THEME) || key.equals(Settings.getNavDrawerItemsPrefKey(hostId))
|| key.equals((Settings.getRemoteBarItemsPrefKey(hostId)))) {
// Explicitly clear cache of resource ids that is maintained in the activity
UIUtils.playPauseIconsLoaded = false;
// restart to apply new theme (actually build an entirely new task stack)
TaskStackBuilder.create(getActivity())
.addNextIntent(new Intent(getActivity(), RemoteActivity.class))
.addNextIntent(new Intent(getActivity(), SettingsActivity.class))
.startActivities();
.addNextIntent(new Intent(getActivity(), RemoteActivity.class))
.addNextIntent(new Intent(getActivity(), SettingsActivity.class))
.startActivities();
}
// If the pause during call is selected, make sure we have permission to read phone state

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<vector android:alpha="1.00" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FFFFFFFF" android:pathData="M19.35,10.03C18.67,6.59 15.64,4 12,4C9.11,4 6.6,5.64 5.35,8.03C2.34,8.36 0,10.9 0,14A6,6 0 0,0 6,20H19A5,5 0 0,0 24,15C24,12.36 21.95,10.22 19.35,10.03Z"/>
</vector>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<vector android:alpha="1.00" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FFFFFFFF" android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z"/>
</vector>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<vector android:alpha="1.00" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FFFFFFFF" android:pathData="M6.76 4.84l-1.8-1.79-1.41 1.41 1.79 1.79 1.42-1.41zM4 10.5H1v2h3v-2zm9-9.95h-2V3.5h2V.55zm7.45 3.91l-1.41-1.41-1.79 1.79 1.41 1.41 1.79-1.79zm-3.21 13.7l1.79 1.8 1.41-1.41-1.8-1.79-1.4 1.4zM20 10.5v2h3v-2h-3zm-8-5c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm-1 16.95h2V19.5h-2v2.95zm-7.45-3.91l1.41 1.41 1.79-1.8-1.41-1.41-1.79 1.8z"/>
</vector>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<vector android:alpha="1.00" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FFFFFFFF" android:pathData="M18 3v2h-2V3H8v2H6V3H4v18h2v-2h2v2h8v-2h2v2h2V3h-2zM8 17H6v-2h2v2zm0-4H6v-2h2v2zm0-4H6V7h2v2zm10 8h-2v-2h2v2zm0-4h-2v-2h2v2zm0-4h-2V7h2v2z"/>
</vector>

View File

@ -150,6 +150,15 @@
android:src="?attr/iconMusic"
android:tint="?attr/defaultButtonColorFilter"
android:contentDescription="@string/music"/>
<ImageButton
android:id="@+id/pvr"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
style="@style/Widget.Button.Borderless"
android:src="?attr/iconPVR"
android:tint="?attr/defaultButtonColorFilter"
android:contentDescription="@string/pvr"/>
<ImageButton
android:id="@+id/pictures"
android:layout_width="0dp"
@ -159,6 +168,51 @@
android:src="?attr/iconPicture"
android:tint="?attr/defaultButtonColorFilter"
android:contentDescription="@string/pictures"/>
<ImageButton
android:id="@+id/videos"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
style="@style/Widget.Button.Borderless"
android:src="?attr/iconVideo"
android:tint="?attr/defaultButtonColorFilter"
android:contentDescription="@string/videos"/>
<!-- <ImageButton
android:id="@+id/favourites"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
style="@style/Widget.Button.Borderless"
android:src="?attr/iconFavourites"
android:tint="?attr/defaultButtonColorFilter"
android:contentDescription="@string/favourites"/> -->
<ImageButton
android:id="@+id/addons"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
style="@style/Widget.Button.Borderless"
android:src="?attr/iconAddons"
android:tint="?attr/defaultButtonColorFilter"
android:contentDescription="@string/addons"/>
<ImageButton
android:id="@+id/weather"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
style="@style/Widget.Button.Borderless"
android:src="?attr/iconWeather"
android:tint="?attr/defaultButtonColorFilter"
android:contentDescription="@string/weather"/>
<ImageButton
android:id="@+id/system"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
style="@style/Widget.Button.Borderless"
android:src="?attr/iconSettings"
android:tint="?attr/defaultButtonColorFilter"
android:contentDescription="@string/system"/>
</LinearLayout>
<RelativeLayout

View File

@ -400,5 +400,10 @@
<string name="by_artist">לפי אמן</string>
<string name="by_artist_and_year">לפי אמן ושנה</string>
<string name="muted">מושתק</string>
<string name="favourites">מועדפים</string>
<string name="remote_bar_items">קיצורים בפס התחתון</string>
<string name="system">הגדרות</string>
<string name="videos">וידאו</string>
<string name="weather">מזג אוויר</string>
</resources>

View File

@ -41,6 +41,21 @@
<!--<item>4</item>-->
</string-array>
<!-- Remote Bar items -->
<string-array name="entries_remote_bar_items">
<item>@string/home</item>
<item>@string/movies</item>
<item>@string/tv_shows</item>
<item>@string/music</item>
<item>@string/pvr</item>
<item>@string/pictures</item>
<item>@string/videos</item>
<!-- <item>@string/favourites</item> -->
<item>@string/addons</item>
<item>@string/weather</item>
<item>@string/system</item>
</string-array>
<!-- Navigation Drawer items -->
<string-array name="entries_nav_drawer_items">
<item>@string/movies</item>
@ -68,6 +83,27 @@
<item>0</item>
</string-array>
<string-array translatable="false" name="entry_values_remote_bar_items">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
<item>7</item>
<item>8</item>
<item>9</item>
</string-array>
<string-array name="default_values_remote_bar_items">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>5</item>
</string-array>
<!-- CAUTION: Keep this synced with the entries ids in NavigationDrawerFragment.java -->
<string-array translatable="false" name="entry_values_nav_drawer_items">
<item>2</item>

View File

@ -49,7 +49,11 @@
<attr name="iconHome" format="reference" />
<attr name="iconAddons" format="reference" />
<attr name="iconFiles" format="reference" />
<attr name="iconVideo" format="reference" />
<attr name="iconPVR" format="reference" />
<attr name="iconFavourites" format="reference" />
<attr name="iconWeather" format="reference" />
<attr name="iconSystem" format="reference" />
<attr name="iconNew" format="reference" />
<attr name="iconNewToolbar" format="reference" />

View File

@ -35,8 +35,12 @@
<string name="addons">Addons</string>
<string name="files">Files</string>
<string name="video">Video</string>
<string name="videos">Videos</string>
<string name="file_browser">File Browser</string>
<string name="pvr">PVR</string>
<string name="favourites">Favourites</string>
<string name="weather">Weather</string>
<string name="system">System</string>
<string name="no_xbmc_configured">No media center configured</string>
<string name="add_xbmc">Add Media Center</string>
@ -339,6 +343,7 @@
<string name="pause_during_calls">Pause during phone call</string>
<string name="use_hardware_volume_keys">Use device volume keys</string>
<string name="vibrate_on_remote">Vibrate on touch</string>
<string name="remote_bar_items">Bottom bar shortcuts</string>
<string name="nav_drawer_items">Side menu shortcuts</string>
<string name="about">About</string>

View File

@ -99,6 +99,9 @@
<item name="iconAddons">@drawable/ic_extension_white_24dp</item>
<item name="iconFiles">@drawable/ic_folder_white_24dp</item>
<item name="iconPVR">@drawable/ic_dvr_white_24dp</item>
<item name="iconVideo">@drawable/ic_video_white_24dp</item>
<item name="iconFavourites">@drawable/ic_star_white_24dp</item>
<item name="iconWeather">@drawable/ic_sunny_white_24dp</item>
<item name="iconNew">@drawable/ic_add_box_white_24dp</item>
<item name="iconNewToolbar">@drawable/ic_add_box_white_24dp</item>
@ -228,6 +231,9 @@
<item name="iconAddons">@drawable/ic_extension_white_24dp</item>
<item name="iconFiles">@drawable/ic_folder_white_24dp</item>
<item name="iconPVR">@drawable/ic_dvr_white_24dp</item>
<item name="iconVideo">@drawable/ic_video_white_24dp</item>
<item name="iconFavourites">@drawable/ic_star_white_24dp</item>
<item name="iconWeather">@drawable/ic_sunny_white_24dp</item>
<item name="iconNew">@drawable/ic_add_box_black_24dp</item>
<item name="iconNewToolbar">@drawable/ic_add_box_white_24dp</item>

View File

@ -37,6 +37,13 @@
android:key="pref_vibrate_remote_buttons"
android:title="@string/vibrate_on_remote"
android:defaultValue="false"/>
<MultiSelectListPreference
android:key="pref_remote_bar_items"
android:title="@string/remote_bar_items"
android:entries="@array/entries_remote_bar_items"
android:entryValues="@array/entry_values_remote_bar_items"
android:defaultValue="@array/default_values_remote_bar_items"/>
</PreferenceCategory>
<PreferenceCategory android:title="@string/application">