mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 12:32:52 +00:00
Merge pull request #388 from lioncash/master
[Android] UI revamp/decoupling.
This commit is contained in:
commit
edb4ec6509
@ -6,7 +6,7 @@
|
||||
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
|
||||
<uses-sdk
|
||||
android:minSdkVersion="9"
|
||||
android:targetSdkVersion="18" />
|
||||
android:targetSdkVersion="19" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
|
||||
@ -15,10 +15,8 @@
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:hasCode="true">
|
||||
<activity android:name="com.retroarch.browser.CoreSelection"/>
|
||||
<activity android:name="com.retroarch.browser.HistorySelection"/>
|
||||
<activity android:name="com.retroarch.browser.DisplayRefreshRateTest"/>
|
||||
<activity android:name="com.retroarch.browser.MainMenuActivity" android:exported="true">
|
||||
<activity android:name="com.retroarch.browser.mainmenu.MainMenuActivity" android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
@ -28,15 +26,7 @@
|
||||
<activity android:name="com.retroarch.browser.FileWrapper"/>
|
||||
<activity android:name="com.retroarch.browser.RetroTVMode"/>
|
||||
|
||||
<activity android:name="com.retroarch.browser.diractivities.DirectoryActivity"/>
|
||||
<activity android:name="com.retroarch.browser.diractivities.ROMActivity"/>
|
||||
<activity android:name="com.retroarch.browser.diractivities.ROMDirActivity"/>
|
||||
<activity android:name="com.retroarch.browser.diractivities.ShaderActivity"/>
|
||||
<activity android:name="com.retroarch.browser.diractivities.OverlayActivity"/>
|
||||
<activity android:name="com.retroarch.browser.diractivities.SRMDirActivity"/>
|
||||
<activity android:name="com.retroarch.browser.diractivities.StateDirActivity"/>
|
||||
<activity android:name="com.retroarch.browser.diractivities.SystemDirActivity"/>
|
||||
<activity android:name="com.retroarch.browser.preferences.fragments.PreferenceActivity" android:theme="@style/Theme.AppCompat" />
|
||||
<activity android:name="com.retroarch.browser.preferences.PreferenceActivity" android:theme="@style/Theme.AppCompat" />
|
||||
<activity android:name="com.retroarch.browser.coremanager.CoreManagerActivity" android:theme="@style/Theme.AppCompat"/>
|
||||
|
||||
<activity android:name="com.retroarch.browser.RetroActivity" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
|
||||
|
12
android/phoenix/res/layout/mainmenu_activity_layout.xml
Normal file
12
android/phoenix/res/layout/mainmenu_activity_layout.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?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="match_parent"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/content_frame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
77
android/phoenix/res/layout/preference_list_fragment.xml
Normal file
77
android/phoenix/res/layout/preference_list_fragment.xml
Normal file
@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** Copyright 2010, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="fill_parent"
|
||||
android:background="@android:color/transparent">
|
||||
|
||||
<ListView android:id="@android:id/list"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="0px"
|
||||
android:layout_weight="1"
|
||||
android:paddingTop="0dip"
|
||||
android:paddingBottom="@dimen/preference_fragment_padding_bottom"
|
||||
android:paddingLeft="@dimen/preference_fragment_padding_side"
|
||||
android:paddingRight="@dimen/preference_fragment_padding_side"
|
||||
android:scrollbarStyle="@integer/preference_fragment_scrollbarStyle"
|
||||
android:clipToPadding="false"
|
||||
android:drawSelectorOnTop="false"
|
||||
android:cacheColorHint="@android:color/transparent"
|
||||
android:scrollbarAlwaysDrawVerticalTrack="true" />
|
||||
|
||||
<TextView android:id="@android:id/empty"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:padding="@dimen/preference_fragment_padding_side"
|
||||
android:gravity="center"
|
||||
android:visibility="gone" />
|
||||
|
||||
<RelativeLayout android:id="@+id/button_bar"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_weight="0"
|
||||
android:visibility="gone">
|
||||
|
||||
<Button android:id="@+id/back_button"
|
||||
android:layout_width="150dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dip"
|
||||
android:layout_alignParentLeft="true"/>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true">
|
||||
|
||||
<Button android:id="@+id/skip_button"
|
||||
android:layout_width="150dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dip"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<Button android:id="@+id/next_button"
|
||||
android:layout_width="150dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dip"/>
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
29
android/phoenix/res/values/dimens.xml
Normal file
29
android/phoenix/res/values/dimens.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/* //device/apps/common/assets/res/any/dimens.xml
|
||||
**
|
||||
** Copyright 2006, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
<resources>
|
||||
|
||||
<!-- Preference fragment padding, bottom -->
|
||||
<dimen name="preference_fragment_padding_bottom">0dp</dimen>
|
||||
<!-- Preference fragment padding, sides -->
|
||||
<dimen name="preference_fragment_padding_side">16dp</dimen>
|
||||
|
||||
<integer name="preference_fragment_scrollbarStyle">0x02000000</integer> <!-- outsideOverlay -->
|
||||
|
||||
</resources>
|
@ -22,7 +22,7 @@
|
||||
<string name="about">About</string>
|
||||
|
||||
<!-- Core Selection Class -->
|
||||
<string name="select_libretro_core">Select Libretro core</string>
|
||||
<string name="select_libretro_core">Select a libretro core</string>
|
||||
|
||||
<!-- Core Manager -->
|
||||
<string name="installed_cores">Installed Cores</string>
|
||||
@ -70,6 +70,13 @@
|
||||
<string name="load_a_core_first">Go to \'Load Core\' and select a core first.</string>
|
||||
<string name="loading_data">Loading [%1$s]…</string>
|
||||
|
||||
<!-- Asset extraction dialog -->
|
||||
<string name="asset_extraction">Asset Extraction</string>
|
||||
|
||||
<!-- GPL cores AlertDialog -->
|
||||
<string name="keep_cores">Keep cores</string>
|
||||
<string name="remove_cores">Remove non-GPL cores</string>
|
||||
|
||||
<!-- Refresh Rate Set OS Class -->
|
||||
<string name="using_os_reported_refresh_rate">Using OS-reported refresh rate of: %1$s Hz.</string>
|
||||
|
||||
@ -118,6 +125,7 @@
|
||||
<string name="touchscreen_overlay_desc">Enable touchscreen overlays (WARNING: Lower-resolution overlays might be more suitable for less powerful devices).</string>
|
||||
<string name="input_overlay">Input overlay</string>
|
||||
<string name="input_overlay_desc">Sets touchscreen overlay config.</string>
|
||||
<string name="input_overlay_select">Select an input overlay</string>
|
||||
<string name="overlay_opacity">Overlay opacity</string>
|
||||
<string name="overlay_opacity_desc">Set the opacity of the touch overlay.</string>
|
||||
<string name="custom_binds">Custom Binds</string>
|
||||
@ -151,19 +159,23 @@
|
||||
<string name="rom_paths">ROM paths</string>
|
||||
<string name="rom_directory">ROM directory</string>
|
||||
<string name="rom_directory_desc">Sets directory where ROM browser will first browse for ROM files.</string>
|
||||
<string name="rom_directory_select">Select a ROM directory</string>
|
||||
<string name="save_files">Save files</string>
|
||||
<string name="enable_custom_dir">Enable custom directory</string>
|
||||
<string name="savefiles_custom_dir">Enables use of custom save file folder. (.srm) save files will be saved and loaded to configured directory. If not enabled, save files will reside in ROM folder.</string>
|
||||
<string name="savefile_directory">Savefile directory</string>
|
||||
<string name="savefile_directory_desc">Sets directory where to save and load game save files.</string>
|
||||
<string name="savefile_directory_select">Select a savefile directory</string>
|
||||
<string name="save_states">Save states</string>
|
||||
<string name="savestates_custom_dir">Enables use of custom save state folder. (.state) save states will be saved and loaded to configured directory. If not enabled, save states will reside in ROM folder.</string>
|
||||
<string name="save_states_custom_dir">Enables use of custom save state folder. (.state) save states will be saved and loaded to configured directory. If not enabled, save states will reside in ROM folder.</string>
|
||||
<string name="save_state_directory">Save state directory</string>
|
||||
<string name="save_state_directory_desc">Sets directory where to save and load game save states.</string>
|
||||
<string name="save_state_directory_select">Select a savestate directory</string>
|
||||
<string name="system">System</string>
|
||||
<string name="system_custom_dir">Enables use of custom system folder. Cores will look for system specific files, like BIOSes, in this folder. If not enabled, it will look in the ROM folder.</string>
|
||||
<string name="system_directory">System directory</string>
|
||||
<string name="system_directory_desc">Sets directory where system files are loaded from.</string>
|
||||
<string name="system_directory_select">Select a system directory</string>
|
||||
|
||||
<!-- General Settings -->
|
||||
<string name="general_options">General</string>
|
||||
@ -210,6 +222,7 @@
|
||||
<string name="first_pass_shader_desc">Enable first pass shader (WARNING: performance varies per device and per shader).</string>
|
||||
<string name="glsl_shader">GLSL shader</string>
|
||||
<string name="glsl_shader_desc">Sets GLES2 style shader.</string>
|
||||
<string name="glsl_shader_select">Select a GLSL shader</string>
|
||||
<string name="fonts">Fonts</string>
|
||||
<string name="onscreen_fonts">On-screen fonts</string>
|
||||
<string name="onscreen_fonts_desc">Enable rendering of on-screen fonts for messages.</string>
|
||||
|
@ -72,13 +72,11 @@
|
||||
android:title="@string/enable" />
|
||||
|
||||
<Preference
|
||||
android:key="inputOverlayDirPref"
|
||||
android:summary="@string/input_overlay_desc"
|
||||
android:title="@string/input_overlay"
|
||||
android:dependency="input_overlay_enable" >
|
||||
<intent
|
||||
android:targetClass="com.retroarch.browser.diractivities.OverlayActivity"
|
||||
android:targetPackage="com.retroarch" />
|
||||
</Preference>
|
||||
android:dependency="input_overlay_enable"/>
|
||||
|
||||
<com.retroarch.browser.preferences.util.SeekbarPreference
|
||||
android:summary="@string/overlay_opacity_desc"
|
||||
android:title="@string/overlay_opacity"
|
||||
|
@ -3,39 +3,33 @@
|
||||
android:title="@string/mainmenu_title" >
|
||||
|
||||
<!-- TV Mode -->
|
||||
<PreferenceScreen android:title="@string/tv_mode">
|
||||
<Preference android:title="@string/tv_mode">
|
||||
<intent
|
||||
android:targetClass="com.retroarch.browser.RetroTVMode"
|
||||
android:targetPackage="com.retroarch" />
|
||||
</PreferenceScreen>
|
||||
</Preference>
|
||||
|
||||
<!-- Load Core -->
|
||||
<PreferenceScreen android:title="@string/load_core">
|
||||
<intent
|
||||
android:targetClass="com.retroarch.browser.CoreSelection"
|
||||
android:targetPackage="com.retroarch" />
|
||||
</PreferenceScreen>
|
||||
<Preference
|
||||
android:key="loadCorePref"
|
||||
android:title="@string/load_core"/>
|
||||
|
||||
<!-- Load Game -->
|
||||
<PreferenceScreen android:title="@string/load_game">
|
||||
<intent
|
||||
android:targetClass="com.retroarch.browser.diractivities.ROMActivity"
|
||||
android:targetPackage="com.retroarch" />
|
||||
</PreferenceScreen>
|
||||
<Preference
|
||||
android:key="loadRomPref"
|
||||
android:title="@string/load_game"/>
|
||||
|
||||
<!-- Load Game (History) -->
|
||||
<PreferenceScreen android:title="@string/load_game_history">
|
||||
<intent
|
||||
android:targetClass="com.retroarch.browser.HistorySelection"
|
||||
android:targetPackage="com.retroarch" />
|
||||
</PreferenceScreen>
|
||||
<Preference
|
||||
android:key="loadRomHistoryPref"
|
||||
android:title="@string/load_game_history"/>
|
||||
|
||||
<!-- Settings -->
|
||||
<PreferenceScreen android:title="@string/settings">
|
||||
<Preference android:title="@string/settings">
|
||||
<intent
|
||||
android:targetClass="com.retroarch.browser.preferences.fragments.PreferenceActivity"
|
||||
android:targetClass="com.retroarch.browser.preferences.PreferenceActivity"
|
||||
android:targetPackage="com.retroarch" />
|
||||
</PreferenceScreen>
|
||||
</Preference>
|
||||
|
||||
<!-- About -->
|
||||
<PreferenceScreen android:title="@string/about">
|
||||
|
@ -3,12 +3,10 @@
|
||||
|
||||
<!-- ROM Paths -->
|
||||
<PreferenceCategory android:title="@string/rom_paths">
|
||||
<Preference android:title="@string/rom_directory"
|
||||
android:summary="@string/rom_directory_desc">
|
||||
<intent
|
||||
android:targetClass="com.retroarch.browser.diractivities.ROMDirActivity"
|
||||
android:targetPackage="com.retroarch" />
|
||||
</Preference>
|
||||
<Preference
|
||||
android:key="romDirPref"
|
||||
android:title="@string/rom_directory"
|
||||
android:summary="@string/rom_directory_desc"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<!-- Save Files -->
|
||||
@ -17,28 +15,24 @@
|
||||
android:summary="@string/savefiles_custom_dir"
|
||||
android:key="savefile_directory_enable"
|
||||
android:defaultValue="false"/>
|
||||
<Preference android:title="@string/savefile_directory"
|
||||
<Preference
|
||||
android:key="srmDirPref"
|
||||
android:title="@string/savefile_directory"
|
||||
android:summary="@string/savefile_directory_desc"
|
||||
android:dependency="savefile_directory_enable">
|
||||
<intent
|
||||
android:targetClass="com.retroarch.browser.diractivities.SRMDirActivity"
|
||||
android:targetPackage="com.retroarch" />
|
||||
</Preference>
|
||||
android:dependency="savefile_directory_enable"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<!-- Save States -->
|
||||
<PreferenceCategory android:title="@string/save_states">
|
||||
<CheckBoxPreference android:title="@string/enable_custom_dir"
|
||||
android:summary="@string/savestates_custom_dir"
|
||||
android:summary="@string/save_states_custom_dir"
|
||||
android:key="savestate_directory_enable"
|
||||
android:defaultValue="false"/>
|
||||
<Preference android:title="@string/save_state_directory"
|
||||
<Preference
|
||||
android:key="saveStateDirPref"
|
||||
android:title="@string/save_state_directory"
|
||||
android:summary="@string/save_state_directory_desc"
|
||||
android:dependency="savestate_directory_enable">
|
||||
<intent
|
||||
android:targetClass="com.retroarch.browser.diractivities.StateDirActivity"
|
||||
android:targetPackage="com.retroarch" />
|
||||
</Preference>
|
||||
android:dependency="savestate_directory_enable"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<!-- System -->
|
||||
@ -47,12 +41,10 @@
|
||||
android:summary="@string/system_custom_dir"
|
||||
android:key="system_directory_enable"
|
||||
android:defaultValue="false"/>
|
||||
<Preference android:title="@string/system_directory"
|
||||
<Preference
|
||||
android:key="systemDirPref"
|
||||
android:title="@string/system_directory"
|
||||
android:summary="@string/system_directory_desc"
|
||||
android:dependency="system_directory_enable">
|
||||
<intent
|
||||
android:targetClass="com.retroarch.browser.diractivities.SystemDirActivity"
|
||||
android:targetPackage="com.retroarch" />
|
||||
</Preference>
|
||||
android:dependency="system_directory_enable"/>
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
|
@ -64,15 +64,11 @@
|
||||
android:defaultValue="false"
|
||||
android:key="video_shader_enable"
|
||||
android:title="@string/first_pass_shader" />
|
||||
|
||||
<Preference
|
||||
android:key="glsl_shader_pref"
|
||||
android:summary="@string/glsl_shader_desc"
|
||||
android:title="@string/glsl_shader"
|
||||
android:dependency="video_shader_enable" >
|
||||
<intent
|
||||
android:targetClass="com.retroarch.browser.diractivities.ShaderActivity"
|
||||
android:targetPackage="com.retroarch" />
|
||||
</Preference>
|
||||
android:dependency="video_shader_enable" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<!-- Fonts -->
|
||||
|
@ -1,42 +1,48 @@
|
||||
package com.retroarch.browser;
|
||||
|
||||
import com.retroarch.R;
|
||||
import com.retroarch.browser.preferences.util.UserPreferences;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.*;
|
||||
import android.media.AudioManager;
|
||||
import android.os.*;
|
||||
import android.widget.*;
|
||||
import android.view.*;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.ListFragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ListView;
|
||||
|
||||
import com.retroarch.R;
|
||||
import com.retroarch.browser.mainmenu.MainMenuActivity;
|
||||
import com.retroarch.browser.preferences.util.UserPreferences;
|
||||
|
||||
/**
|
||||
* {@link ListActivity} subclass that displays the list
|
||||
* {@link ListFragment} subclass that displays the list
|
||||
* of selectable cores for emulating games.
|
||||
*/
|
||||
public final class CoreSelection extends ListActivity {
|
||||
public final class CoreSelection extends DialogFragment
|
||||
{
|
||||
private IconAdapter<ModuleWrapper> adapter;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
||||
{
|
||||
// Inflate the ListView we're using.
|
||||
final ListView coreList = (ListView) inflater.inflate(R.layout.line_list, container, false);
|
||||
coreList.setOnItemClickListener(onClickListener);
|
||||
|
||||
// Set the title of the dialog
|
||||
getDialog().setTitle(R.string.select_libretro_core);
|
||||
|
||||
final String cpuInfo = UserPreferences.readCPUInfo();
|
||||
final boolean cpuIsNeon = cpuInfo.contains("neon");
|
||||
|
||||
// Setup the layout
|
||||
setContentView(R.layout.line_list);
|
||||
|
||||
// Set the activity title.
|
||||
setTitle(R.string.select_libretro_core);
|
||||
|
||||
// Populate the list
|
||||
final List<ModuleWrapper> cores = new ArrayList<ModuleWrapper>();
|
||||
final File[] libs = new File(getApplicationInfo().dataDir, "/cores").listFiles();
|
||||
final File[] libs = new File(getActivity().getApplicationInfo().dataDir, "/cores").listFiles();
|
||||
for (final File lib : libs) {
|
||||
String libName = lib.getName();
|
||||
|
||||
@ -46,13 +52,15 @@ public final class CoreSelection extends ListActivity {
|
||||
|
||||
// If we have a NEON version with NEON capable CPU,
|
||||
// never append a non-NEON version.
|
||||
if (cpuIsNeon && !libName.contains("neon")) {
|
||||
if (cpuIsNeon && !libName.contains("neon"))
|
||||
{
|
||||
boolean hasNeonVersion = false;
|
||||
for (final File lib_ : libs) {
|
||||
for (final File lib_ : libs)
|
||||
{
|
||||
String otherName = lib_.getName();
|
||||
String baseName = libName.replace(".so", "");
|
||||
if (otherName.contains("neon")
|
||||
&& otherName.startsWith(baseName)) {
|
||||
if (otherName.contains("neon") && otherName.startsWith(baseName))
|
||||
{
|
||||
hasNeonVersion = true;
|
||||
break;
|
||||
}
|
||||
@ -62,24 +70,28 @@ public final class CoreSelection extends ListActivity {
|
||||
continue;
|
||||
}
|
||||
|
||||
cores.add(new ModuleWrapper(this, lib));
|
||||
cores.add(new ModuleWrapper(getActivity(), lib));
|
||||
}
|
||||
|
||||
// Sort the list of cores alphabetically
|
||||
Collections.sort(cores);
|
||||
|
||||
// Initialize the IconAdapter with the list of cores.
|
||||
adapter = new IconAdapter<ModuleWrapper>(this, R.layout.line_list_item, cores);
|
||||
setListAdapter(adapter);
|
||||
adapter = new IconAdapter<ModuleWrapper>(getActivity(), R.layout.line_list_item, cores);
|
||||
coreList.setAdapter(adapter);
|
||||
|
||||
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||
return coreList;
|
||||
}
|
||||
|
||||
private final OnItemClickListener onClickListener = new OnItemClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onListItemClick(ListView listView, View view, int position, long id) {
|
||||
public void onItemClick(AdapterView<?> listView, View view, int position, long id)
|
||||
{
|
||||
final ModuleWrapper item = adapter.getItem(position);
|
||||
MainMenuActivity.getInstance().setModule(item.getUnderlyingFile().getAbsolutePath(), item.getText());
|
||||
UserPreferences.updateConfigFile(this);
|
||||
finish();
|
||||
((MainMenuActivity)getActivity()).setModule(item.getUnderlyingFile().getAbsolutePath(), item.getText());
|
||||
UserPreferences.updateConfigFile(getActivity());
|
||||
dismiss();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -7,45 +7,62 @@ import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import com.retroarch.R;
|
||||
import com.retroarch.browser.mainmenu.MainMenuActivity;
|
||||
import com.retroarch.browser.preferences.util.UserPreferences;
|
||||
|
||||
import android.app.ListActivity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.ListFragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ListView;
|
||||
import android.widget.Toast;
|
||||
|
||||
/**
|
||||
* Represents the {@link ListActivity} responsible
|
||||
* Represents the {@link ListFragment} responsible
|
||||
* for displaying the list of previously played games.
|
||||
*/
|
||||
public final class HistorySelection extends ListActivity {
|
||||
|
||||
public final class HistorySelection extends DialogFragment
|
||||
{
|
||||
private FragmentActivity ctx;
|
||||
private IconAdapter<HistoryWrapper> adapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Setup the layout.
|
||||
setContentView(R.layout.line_list);
|
||||
// Cache the context
|
||||
this.ctx = getActivity();
|
||||
}
|
||||
|
||||
// Setup the list
|
||||
adapter = new IconAdapter<HistoryWrapper>(this, R.layout.line_list_item);
|
||||
setListAdapter(adapter);
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
||||
{
|
||||
ListView rootView = (ListView) inflater.inflate(R.layout.line_list, container, false);
|
||||
rootView.setOnItemClickListener(onItemClickListener);
|
||||
|
||||
// Set activity title.
|
||||
setTitle(R.string.recently_played_games);
|
||||
// Set the title for this dialog.
|
||||
getDialog().setTitle(R.string.load_game_history);
|
||||
|
||||
File history = new File(getApplicationInfo().dataDir, "retroarch-history.txt");
|
||||
// Setup the list adapter
|
||||
adapter = new IconAdapter<HistoryWrapper>(ctx, R.layout.line_list_item);
|
||||
|
||||
try {
|
||||
// Populate the adapter
|
||||
File history = new File(ctx.getApplicationInfo().dataDir, "retroarch-history.txt");
|
||||
try
|
||||
{
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(
|
||||
new FileInputStream(history)));
|
||||
|
||||
for (;;) {
|
||||
for (;;)
|
||||
{
|
||||
String game = br.readLine();
|
||||
String core = br.readLine();
|
||||
String name = br.readLine();
|
||||
@ -55,30 +72,42 @@ public final class HistorySelection extends ListActivity {
|
||||
adapter.add(new HistoryWrapper(game, core, name));
|
||||
}
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
catch (IOException ignored)
|
||||
{
|
||||
}
|
||||
|
||||
// Set the adapter
|
||||
rootView.setAdapter(adapter);
|
||||
return rootView;
|
||||
}
|
||||
|
||||
private final OnItemClickListener onItemClickListener = new OnItemClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onListItemClick(ListView listView, View view, int position, long id) {
|
||||
public void onItemClick(AdapterView<?> listView, View view, int position, long id)
|
||||
{
|
||||
final HistoryWrapper item = adapter.getItem(position);
|
||||
final String gamePath = item.getGamePath();
|
||||
final String corePath = item.getCorePath();
|
||||
|
||||
MainMenuActivity.getInstance().setModule(corePath, item.getCoreName());
|
||||
// Set the core the selected game uses.
|
||||
((MainMenuActivity)getActivity()).setModule(corePath, item.getCoreName());
|
||||
|
||||
String current_ime = Settings.Secure.getString(getContentResolver(),
|
||||
// Update the config accordingly.
|
||||
UserPreferences.updateConfigFile(ctx);
|
||||
|
||||
// Launch the game.
|
||||
String current_ime = Settings.Secure.getString(ctx.getContentResolver(),
|
||||
Settings.Secure.DEFAULT_INPUT_METHOD);
|
||||
|
||||
UserPreferences.updateConfigFile(this);
|
||||
|
||||
Toast.makeText(this, String.format(getString(R.string.loading_gamepath), gamePath), Toast.LENGTH_SHORT).show();
|
||||
Intent myIntent = new Intent(this, RetroActivity.class);
|
||||
Toast.makeText(ctx, String.format(getString(R.string.loading_gamepath), gamePath), Toast.LENGTH_SHORT).show();
|
||||
Intent myIntent = new Intent(ctx, RetroActivity.class);
|
||||
myIntent.putExtra("ROM", gamePath);
|
||||
myIntent.putExtra("LIBRETRO", corePath);
|
||||
myIntent.putExtra("CONFIGFILE", UserPreferences.getDefaultConfigPath(this));
|
||||
myIntent.putExtra("CONFIGFILE", UserPreferences.getDefaultConfigPath(ctx));
|
||||
myIntent.putExtra("IME", current_ime);
|
||||
startActivity(myIntent);
|
||||
finish();
|
||||
dismiss();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,409 +0,0 @@
|
||||
package com.retroarch.browser;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import com.retroarch.R;
|
||||
import com.retroarch.browser.preferences.util.UserPreferences;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
/**
|
||||
* {@link PreferenceActivity} subclass that provides all of the
|
||||
* functionality of the main menu screen.
|
||||
*/
|
||||
public final class MainMenuActivity extends PreferenceActivity {
|
||||
private static MainMenuActivity instance = null;
|
||||
private static final int ACTIVITY_LOAD_ROM = 0;
|
||||
private static final int ACTIVITY_RETROARCH = 1;
|
||||
private static final String TAG = "MainMenu";
|
||||
private static String libretro_path;
|
||||
private static String libretro_name;
|
||||
|
||||
private void showGPLWaiver() {
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.gpl_waiver)
|
||||
.setMessage(R.string.gpl_waiver_desc)
|
||||
.setPositiveButton("Keep", null)
|
||||
.setNegativeButton("Remove non-GPL cores",
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
final File[] libs = new File(getApplicationInfo().dataDir, "/cores").listFiles();
|
||||
for (final File lib : libs) {
|
||||
ModuleWrapper module = new ModuleWrapper(getApplicationContext(), lib);
|
||||
|
||||
boolean gplv3 = module.getCoreLicense().equals("GPLv3");
|
||||
boolean gplv2 = module.getCoreLicense().equals("GPLv2");
|
||||
|
||||
if (!gplv3 && !gplv2) {
|
||||
String libName = lib.getName();
|
||||
Log.i("GPL WAIVER", "Deleting non-GPL core" + libName + "...");
|
||||
lib.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
alert.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Load the main menu XML.
|
||||
addPreferencesFromResource(R.xml.main_menu);
|
||||
|
||||
// Cache an instance of this class (TODO: Bad practice, kill this somehow).
|
||||
instance = this;
|
||||
|
||||
// Get libretro path and name.
|
||||
SharedPreferences prefs = UserPreferences.getPreferences(this);
|
||||
libretro_path = prefs.getString("libretro_path", getApplicationInfo().dataDir + "/cores");
|
||||
libretro_name = prefs.getString("libretro_name", getString(R.string.no_core));
|
||||
|
||||
// Bind audio stream to hardware controls.
|
||||
setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||
|
||||
// Extract assets.
|
||||
extractAssets();
|
||||
|
||||
if (!prefs.getBoolean("first_time_refreshrate_calculate", false)) {
|
||||
prefs.edit().putBoolean("first_time_refreshrate_calculate", true).commit();
|
||||
|
||||
if (!detectDevice(false)) {
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.welcome_to_retroarch)
|
||||
.setMessage(R.string.welcome_to_retroarch_desc)
|
||||
.setPositiveButton("OK", null);
|
||||
alert.show();
|
||||
}
|
||||
|
||||
showGPLWaiver();
|
||||
}
|
||||
|
||||
Intent startedByIntent = getIntent();
|
||||
if (startedByIntent.getStringExtra("ROM") != null && startedByIntent.getStringExtra("LIBRETRO") != null) {
|
||||
if (savedInstanceState == null || !savedInstanceState.getBoolean("romexec"))
|
||||
loadRomExternal(startedByIntent.getStringExtra("ROM"),
|
||||
startedByIntent.getStringExtra("LIBRETRO"));
|
||||
else
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
public static MainMenuActivity getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private int getVersionCode() {
|
||||
int version = 0;
|
||||
try {
|
||||
version = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
|
||||
} catch (NameNotFoundException e) {
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
private boolean areAssetsExtracted() {
|
||||
int version = getVersionCode();
|
||||
|
||||
try {
|
||||
String dataDir = getApplicationInfo().dataDir;
|
||||
File cacheVersion = new File(dataDir, ".cacheversion");
|
||||
if (cacheVersion.isFile() && cacheVersion.canRead() && cacheVersion.canWrite()) {
|
||||
DataInputStream cacheStream = new DataInputStream(
|
||||
new FileInputStream(cacheVersion));
|
||||
|
||||
int currentCacheVersion = 0;
|
||||
try {
|
||||
currentCacheVersion = cacheStream.readInt();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
cacheStream.close();
|
||||
|
||||
if (currentCacheVersion == version) {
|
||||
Log.i("ASSETS", "Assets already extracted, skipping...");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Failed to extract assets to cache.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract assets from native code. Doing it from Java side is apparently unbearably slow ...
|
||||
private void extractAssetsThread() {
|
||||
try {
|
||||
String dataDir = getApplicationInfo().dataDir;
|
||||
|
||||
String apk = getApplicationInfo().sourceDir;
|
||||
Log.i(TAG, "Extracting RetroArch assets from: " + apk + " ...");
|
||||
boolean success = NativeInterface.extractArchiveTo(apk, "assets", dataDir);
|
||||
if (!success) {
|
||||
throw new IOException("Failed to extract assets ...");
|
||||
}
|
||||
Log.i(TAG, "Extracted assets ...");
|
||||
|
||||
File cacheVersion = new File(dataDir, ".cacheversion");
|
||||
DataOutputStream outputCacheVersion = new DataOutputStream(
|
||||
new FileOutputStream(cacheVersion, false));
|
||||
outputCacheVersion.writeInt(getVersionCode());
|
||||
outputCacheVersion.close();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Failed to extract assets to cache.");
|
||||
}
|
||||
}
|
||||
|
||||
private void extractAssets() {
|
||||
if (areAssetsExtracted())
|
||||
return;
|
||||
|
||||
final Dialog dialog = new Dialog(this);
|
||||
final Handler handler = new Handler();
|
||||
dialog.setContentView(R.layout.assets);
|
||||
dialog.setCancelable(false);
|
||||
dialog.setTitle("Asset extraction");
|
||||
|
||||
// Java is fun :)
|
||||
Thread assetsThread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
extractAssetsThread();
|
||||
handler.post(new Runnable() {
|
||||
public void run() {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
assetsThread.start();
|
||||
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public void setModule(String core_path, String core_name) {
|
||||
UserPreferences.updateConfigFile(this);
|
||||
|
||||
libretro_path = core_path;
|
||||
libretro_name = core_name;
|
||||
|
||||
SharedPreferences prefs = UserPreferences.getPreferences(this);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("libretro_path", libretro_path);
|
||||
edit.putString("libretro_name", libretro_name);
|
||||
edit.commit();
|
||||
|
||||
// Set the title section to contain the name of the selected core.
|
||||
setCoreTitle(libretro_name);
|
||||
|
||||
}
|
||||
|
||||
public void setCoreTitle(String core_name) {
|
||||
setTitle("RetroArch : " + core_name);
|
||||
}
|
||||
|
||||
private boolean detectDevice(boolean show_dialog) {
|
||||
boolean retval = false;
|
||||
|
||||
final Context ctx = this;
|
||||
final boolean mentionPlayStore = !Build.MODEL.equals("OUYA Console");
|
||||
final String message = (mentionPlayStore ? getString(R.string.detect_device_msg_general) : getString(R.string.detect_device_msg_ouya));
|
||||
|
||||
Log.i("Device MODEL", Build.MODEL);
|
||||
if (Build.MODEL.equals("SHIELD")) {
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.nvidia_shield_detected)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(R.string.ok,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
SharedPreferences prefs = UserPreferences.getPreferences(MainMenuActivity.this);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("video_refresh_rate", Double.toString(60.00d));
|
||||
edit.putBoolean("input_overlay_enable", false);
|
||||
edit.putBoolean("input_autodetect_enable", true);
|
||||
edit.putString("audio_latency", "64");
|
||||
edit.putBoolean("audio_latency_auto", true);
|
||||
edit.commit();
|
||||
UserPreferences.updateConfigFile(ctx);
|
||||
}
|
||||
});
|
||||
alert.show();
|
||||
retval = true;
|
||||
} else if (Build.MODEL.equals("GAMEMID_BT")) {
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.game_mid_detected)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(R.string.ok,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
SharedPreferences prefs = UserPreferences.getPreferences(MainMenuActivity.this);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("input_overlay_enable", false);
|
||||
edit.putBoolean("input_autodetect_enable", true);
|
||||
edit.putString("audio_latency", "160");
|
||||
edit.putBoolean("audio_latency_auto", false);
|
||||
edit.commit();
|
||||
UserPreferences.updateConfigFile(ctx);
|
||||
}
|
||||
});
|
||||
alert.show();
|
||||
retval = true;
|
||||
} else if (Build.MODEL.equals("OUYA Console")) {
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.ouya_detected)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(R.string.ok,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
SharedPreferences prefs = UserPreferences.getPreferences(MainMenuActivity.this);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("input_overlay_enable", false);
|
||||
edit.putBoolean("input_autodetect_enable", true);
|
||||
edit.putString("audio_latency", "64");
|
||||
edit.putBoolean("audio_latency_auto", true);
|
||||
edit.commit();
|
||||
UserPreferences.updateConfigFile(ctx);
|
||||
}
|
||||
});
|
||||
alert.show();
|
||||
retval = true;
|
||||
} else if (Build.MODEL.equals("R800x")) {
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.xperia_play_detected)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(R.string.ok,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
SharedPreferences prefs = UserPreferences.getPreferences(MainMenuActivity.this);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("video_threaded", false);
|
||||
edit.putBoolean("input_overlay_enable", false);
|
||||
edit.putBoolean("input_autodetect_enable", true);
|
||||
edit.putString("video_refresh_rate", Double.toString(59.19132938771038));
|
||||
edit.putString("audio_latency", "128");
|
||||
edit.putBoolean("audio_latency_auto", false);
|
||||
edit.commit();
|
||||
UserPreferences.updateConfigFile(ctx);
|
||||
}
|
||||
});
|
||||
alert.show();
|
||||
retval = true;
|
||||
} else if (Build.ID.equals("JSS15J")) {
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.nexus_7_2013_detected)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(R.string.ok,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
SharedPreferences prefs = UserPreferences.getPreferences(MainMenuActivity.this);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("video_refresh_rate", Double.toString(59.65));
|
||||
edit.putString("audio_latency", "64");
|
||||
edit.putBoolean("audio_latency_auto", false);
|
||||
edit.commit();
|
||||
UserPreferences.updateConfigFile(ctx);
|
||||
}
|
||||
});
|
||||
alert.show();
|
||||
retval = true;
|
||||
}
|
||||
|
||||
if (show_dialog) {
|
||||
Toast.makeText(this, R.string.no_optimal_settings, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startActivity(Intent intent) {
|
||||
if (intent.getComponent().getClassName()
|
||||
.equals("com.retroarch.browser.diractivities.ROMActivity")) {
|
||||
if (!new File(libretro_path).isDirectory()) {
|
||||
super.startActivityForResult(intent, ACTIVITY_LOAD_ROM);
|
||||
} else {
|
||||
Toast.makeText(this, R.string.load_a_core_first, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
} else {
|
||||
super.startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int reqCode, int resCode, Intent data) {
|
||||
switch (reqCode) {
|
||||
case ACTIVITY_LOAD_ROM: {
|
||||
if (data.getStringExtra("PATH") != null) {
|
||||
UserPreferences.updateConfigFile(this);
|
||||
String current_ime = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
|
||||
Toast.makeText(this,String.format(getString(R.string.loading_data), data.getStringExtra("PATH")), Toast.LENGTH_SHORT).show();
|
||||
Intent myIntent = new Intent(this, RetroActivity.class);
|
||||
myIntent.putExtra("ROM", data.getStringExtra("PATH"));
|
||||
myIntent.putExtra("LIBRETRO", libretro_path);
|
||||
myIntent.putExtra("CONFIGFILE", UserPreferences.getDefaultConfigPath(this));
|
||||
myIntent.putExtra("IME", current_ime);
|
||||
startActivityForResult(myIntent, ACTIVITY_RETROARCH);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ACTIVITY_RETROARCH: {
|
||||
Log.i(TAG, "RetroArch finished running.");
|
||||
UserPreferences.readbackConfigFile(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle data) {
|
||||
super.onSaveInstanceState(data);
|
||||
data.putCharSequence("title", getTitle());
|
||||
data.putBoolean("romexec", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Bundle state) {
|
||||
super.onRestoreInstanceState(state);
|
||||
|
||||
if (state != null) {
|
||||
setTitle(state.getCharSequence("title"));
|
||||
}
|
||||
}
|
||||
|
||||
private void loadRomExternal(String rom, String core) {
|
||||
UserPreferences.updateConfigFile(this);
|
||||
String current_ime = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
|
||||
Toast.makeText(this, String.format(getString(R.string.loading_data), rom), Toast.LENGTH_SHORT).show();
|
||||
Intent myIntent = new Intent(this, RetroActivity.class);
|
||||
myIntent.putExtra("ROM", rom);
|
||||
myIntent.putExtra("LIBRETRO", core);
|
||||
myIntent.putExtra("CONFIGFILE", UserPreferences.getDefaultConfigPath(this));
|
||||
myIntent.putExtra("IME", current_ime);
|
||||
startActivity(myIntent);
|
||||
}
|
||||
}
|
@ -1,20 +1,24 @@
|
||||
package com.retroarch.browser;
|
||||
|
||||
import com.retroarch.browser.preferences.util.UserPreferences;
|
||||
|
||||
import android.app.NativeActivity;
|
||||
import android.os.Bundle;
|
||||
|
||||
public final class RetroActivity extends NativeActivity {
|
||||
|
||||
public final class RetroActivity extends NativeActivity
|
||||
{
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstance) {
|
||||
super.onCreate(savedInstance);
|
||||
public void onDestroy()
|
||||
{
|
||||
UserPreferences.readbackConfigFile(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
public void onLowMemory()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrimMemory(int level) {
|
||||
public void onTrimMemory(int level)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -6,51 +6,37 @@ import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* The {@link Activity} derivative responsible for displaying the TV Mode feature.
|
||||
*/
|
||||
public final class RetroTVMode extends Activity {
|
||||
private static final String TAG = "RetroTVMode";
|
||||
private static final int ACTIVITY_RETROARCH = 1;
|
||||
|
||||
public final class RetroTVMode extends Activity
|
||||
{
|
||||
// Need to do this wonky logic as we have to keep this activity alive until
|
||||
// RetroArch is done running.
|
||||
// Have to readback config right after RetroArch has run to avoid potential
|
||||
// broken config state.
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (savedInstanceState == null
|
||||
|| !savedInstanceState.getBoolean("started", false)) {
|
||||
if (savedInstanceState == null || !savedInstanceState.getBoolean("started", false))
|
||||
{
|
||||
UserPreferences.updateConfigFile(this);
|
||||
|
||||
Intent myIntent = new Intent(this, RetroActivity.class);
|
||||
String current_ime = Settings.Secure.getString(
|
||||
getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
|
||||
myIntent.putExtra("CONFIGFILE",
|
||||
UserPreferences.getDefaultConfigPath(this));
|
||||
String current_ime = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
|
||||
myIntent.putExtra("CONFIGFILE", UserPreferences.getDefaultConfigPath(this));
|
||||
myIntent.putExtra("IME", current_ime);
|
||||
startActivityForResult(myIntent, ACTIVITY_RETROARCH);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int reqCode, int resCode, Intent data) {
|
||||
switch (reqCode) {
|
||||
case ACTIVITY_RETROARCH: {
|
||||
Log.i(TAG, "RetroArch finished running.");
|
||||
UserPreferences.readbackConfigFile(this);
|
||||
startActivity(myIntent);
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle savedInstanceState) {
|
||||
protected void onSaveInstanceState(Bundle savedInstanceState)
|
||||
{
|
||||
savedInstanceState.putBoolean("started", true);
|
||||
}
|
||||
}
|
||||
|
@ -1,271 +0,0 @@
|
||||
package com.retroarch.browser.diractivities;
|
||||
|
||||
import com.retroarch.R;
|
||||
import com.retroarch.browser.FileWrapper;
|
||||
import com.retroarch.browser.IconAdapter;
|
||||
import com.retroarch.browser.preferences.util.UserPreferences;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
import android.content.*;
|
||||
import android.app.*;
|
||||
import android.media.AudioManager;
|
||||
import android.os.*;
|
||||
import android.widget.*;
|
||||
import android.view.*;
|
||||
|
||||
/**
|
||||
* {@link ListActivity} subclass that provides a file-browser
|
||||
* like UI for browsing for specific files.
|
||||
* <p>
|
||||
* This file browser also allows for custom filtering
|
||||
* depending on the type of class that inherits it.
|
||||
* <p>
|
||||
* This file browser also uses an implementation of a
|
||||
* backstack for remembering previously browsed folders
|
||||
* within this DirectoryActivity.
|
||||
*/
|
||||
public class DirectoryActivity extends ListActivity {
|
||||
private IconAdapter<FileWrapper> adapter;
|
||||
private File listedDirectory;
|
||||
|
||||
public static class BackStackItem implements Parcelable {
|
||||
private final String path;
|
||||
private final boolean parentIsBack;
|
||||
|
||||
public BackStackItem(String path, boolean parentIsBack) {
|
||||
this.path = path;
|
||||
this.parentIsBack = parentIsBack;
|
||||
}
|
||||
|
||||
private BackStackItem(Parcel in) {
|
||||
this.path = in.readString();
|
||||
this.parentIsBack = in.readInt() != 0;
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeString(path);
|
||||
out.writeInt(parentIsBack ? 1 : 0);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<BackStackItem> CREATOR = new Parcelable.Creator<BackStackItem>() {
|
||||
public BackStackItem createFromParcel(Parcel in) {
|
||||
return new BackStackItem(in);
|
||||
}
|
||||
|
||||
public BackStackItem[] newArray(int size) {
|
||||
return new BackStackItem[size];
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
private ArrayList<BackStackItem> backStack;
|
||||
|
||||
protected String startDirectory;
|
||||
protected String pathSettingKey;
|
||||
|
||||
protected void setStartDirectory(String path) {
|
||||
startDirectory = path;
|
||||
}
|
||||
|
||||
protected void setPathSettingKey(String key) {
|
||||
pathSettingKey = key;
|
||||
}
|
||||
|
||||
private boolean isDirectoryTarget;
|
||||
protected void setIsDirectoryTarget(boolean enable) {
|
||||
isDirectoryTarget = enable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.line_list);
|
||||
|
||||
// Setup the list
|
||||
adapter = new IconAdapter<FileWrapper>(this, R.layout.line_list_item);
|
||||
setListAdapter(adapter);
|
||||
|
||||
// Load Directory
|
||||
if (savedInstanceState != null) {
|
||||
backStack = savedInstanceState.getParcelableArrayList("BACKSTACK");
|
||||
}
|
||||
|
||||
if (backStack == null || backStack.isEmpty()) {
|
||||
backStack = new ArrayList<BackStackItem>();
|
||||
String startPath = (startDirectory == null || startDirectory.isEmpty()) ? Environment
|
||||
.getExternalStorageDirectory().getPath() : startDirectory;
|
||||
backStack.add(new BackStackItem(startPath, false));
|
||||
}
|
||||
|
||||
wrapFiles();
|
||||
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle aState) {
|
||||
super.onSaveInstanceState(aState);
|
||||
aState.putParcelableArrayList("BACKSTACK", backStack);
|
||||
}
|
||||
|
||||
private void finishWithPath(String path) {
|
||||
if (pathSettingKey != null && !pathSettingKey.isEmpty()) {
|
||||
SharedPreferences settings = UserPreferences.getPreferences(this);
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.putString(pathSettingKey, path);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra("PATH", path);
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(ListView listView, View aView, int position, long id) {
|
||||
final FileWrapper item = adapter.getItem(position);
|
||||
|
||||
if (item.isParentItem() && backStack.get(backStack.size() - 1).parentIsBack) {
|
||||
backStack.remove(backStack.size() - 1);
|
||||
wrapFiles();
|
||||
return;
|
||||
} else if (item.isDirSelectItem()) {
|
||||
finishWithPath(listedDirectory.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
|
||||
final File selected = item.isParentItem() ? listedDirectory.getParentFile() : item.getFile();
|
||||
|
||||
if (selected.isDirectory()) {
|
||||
backStack.add(new BackStackItem(selected.getAbsolutePath(),
|
||||
!item.isParentItem()));
|
||||
wrapFiles();
|
||||
} else {
|
||||
String filePath = selected.getAbsolutePath();
|
||||
finishWithPath(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
if (backStack.size() > 1) {
|
||||
backStack.remove(backStack.size() - 1);
|
||||
wrapFiles();
|
||||
} else {
|
||||
Intent intent = new Intent();
|
||||
setResult(RESULT_CANCELED, intent);
|
||||
finish();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
private ArrayList<String> allowedExt;
|
||||
private ArrayList<String> disallowedExt;
|
||||
|
||||
private boolean filterPath(String path) {
|
||||
if (disallowedExt != null) {
|
||||
for (String ext : disallowedExt)
|
||||
if (path.endsWith(ext))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (allowedExt != null) {
|
||||
for (String ext : allowedExt)
|
||||
if (path.endsWith(ext))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows specifying an allowed file extension.
|
||||
* <p>
|
||||
* Any files that contain this file extension will be shown
|
||||
* within the DirectoryActivity file browser. Those that don't
|
||||
* contain this extension will not be shows.
|
||||
* <p>
|
||||
* It is possible to specify more than one allowed extension by
|
||||
* simply calling this method with a different file extension specified.
|
||||
*
|
||||
* @param ext The file extension to allow being shown in this DirectoryActivity.
|
||||
*/
|
||||
protected void addAllowedExt(String ext) {
|
||||
if (allowedExt == null)
|
||||
allowedExt = new ArrayList<String>();
|
||||
|
||||
allowedExt.add(ext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows specifying a disallowed file extension.
|
||||
* <p>
|
||||
* Any files that contain this file extension will not be shown
|
||||
* within the DirectoryActivity file browser.
|
||||
* <p>
|
||||
* It is possible to specify more than one disallowed extension by
|
||||
* simply calling this method with a different file extension specified.
|
||||
*
|
||||
* @param ext The file extension to hide from being shown in this DirectoryActivity.
|
||||
*/
|
||||
protected void addDisallowedExt(String ext) {
|
||||
if (disallowedExt == null)
|
||||
disallowedExt = new ArrayList<String>();
|
||||
|
||||
disallowedExt.add(ext);
|
||||
}
|
||||
|
||||
private void wrapFiles() {
|
||||
listedDirectory = new File(backStack.get(backStack.size() - 1).path);
|
||||
|
||||
if (!listedDirectory.isDirectory()) {
|
||||
throw new IllegalArgumentException("Directory is not valid.");
|
||||
}
|
||||
|
||||
adapter.clear();
|
||||
setTitle(listedDirectory.getAbsolutePath());
|
||||
|
||||
if (isDirectoryTarget)
|
||||
adapter.add(new FileWrapper(null, FileWrapper.DIRSELECT, true));
|
||||
|
||||
if (listedDirectory.getParentFile() != null)
|
||||
adapter.add(new FileWrapper(null, FileWrapper.PARENT, true));
|
||||
|
||||
// Copy new items
|
||||
final File[] files = listedDirectory.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
String path = file.getName();
|
||||
|
||||
boolean allowFile = file.isDirectory() || (filterPath(path) && !isDirectoryTarget);
|
||||
|
||||
if (allowFile)
|
||||
adapter.add(new FileWrapper(file, FileWrapper.FILE, true));
|
||||
}
|
||||
}
|
||||
|
||||
// Sort items
|
||||
adapter.sort(new Comparator<FileWrapper>() {
|
||||
@Override
|
||||
public int compare(FileWrapper left, FileWrapper right) {
|
||||
return left.compareTo(right);
|
||||
};
|
||||
});
|
||||
|
||||
// Update
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package com.retroarch.browser.diractivities;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* {@link DirectoryActivity} subclass used for the sole
|
||||
* purpose of navigating the Android filesystem for input overlays.
|
||||
* @author Lioncash-yay
|
||||
*
|
||||
*/
|
||||
public final class OverlayActivity extends DirectoryActivity {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
File overlayDir = new File(getApplicationInfo().dataDir, "overlays");
|
||||
if (overlayDir.exists())
|
||||
super.setStartDirectory(overlayDir.getAbsolutePath());
|
||||
|
||||
super.addAllowedExt(".cfg");
|
||||
super.setPathSettingKey("input_overlay");
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package com.retroarch.browser.diractivities;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.retroarch.browser.preferences.util.UserPreferences;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* {@link DirectoryActivity} subclass used for the sole
|
||||
* purpose of navigating the Android filesystem for selecting
|
||||
* a ROM file to execute during emulation.
|
||||
*/
|
||||
public final class ROMActivity extends DirectoryActivity {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
SharedPreferences prefs = UserPreferences.getPreferences(this);
|
||||
String startPath = prefs.getString("rgui_browser_directory", "");
|
||||
if (!startPath.isEmpty() && new File(startPath).exists())
|
||||
super.setStartDirectory(startPath);
|
||||
|
||||
super.addDisallowedExt(".state");
|
||||
super.addDisallowedExt(".srm");
|
||||
super.addDisallowedExt(".state.auto");
|
||||
super.addDisallowedExt(".rtc");
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package com.retroarch.browser.diractivities;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* {@link DirectoryActivity} subclass used for the sole
|
||||
* purpose of navigating the Android filesystem to select
|
||||
* a custom ROM directory.
|
||||
*/
|
||||
public final class ROMDirActivity extends DirectoryActivity {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.setPathSettingKey("rgui_browser_directory");
|
||||
super.setIsDirectoryTarget(true);
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package com.retroarch.browser.diractivities;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* {@link DirectoryActivity} subclass used for the sole
|
||||
* purpose of navigating the Android filesystem for selecting
|
||||
* a custom save file directory.
|
||||
*/
|
||||
public final class SRMDirActivity extends DirectoryActivity {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.setPathSettingKey("savefile_directory");
|
||||
super.setIsDirectoryTarget(true);
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package com.retroarch.browser.diractivities;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* {@link DirectoryActivity} subclass used for the sole
|
||||
* purpose of navigating the Android filesystem for selecting
|
||||
* a shader to use during emulation.
|
||||
*/
|
||||
public final class ShaderActivity extends DirectoryActivity {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
File shaderDir = new File(getApplicationInfo().dataDir, "shaders_glsl");
|
||||
if (shaderDir.exists())
|
||||
super.setStartDirectory(shaderDir.getAbsolutePath());
|
||||
|
||||
super.addAllowedExt(".glsl");
|
||||
super.setPathSettingKey("video_shader");
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package com.retroarch.browser.diractivities;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* {@link DirectoryActivity} subclass used for the sole
|
||||
* purpose of navigating the Android filesystem to select
|
||||
* a custom save state directory.
|
||||
*/
|
||||
public final class StateDirActivity extends DirectoryActivity {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.setPathSettingKey("savestate_directory");
|
||||
super.setIsDirectoryTarget(true);
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.retroarch.browser.diractivities;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* {@link DirectoryActivity} subclass used for the sole
|
||||
* purpose of navigating the Android filesystem for selecting
|
||||
* a custom 'System' directory that the cores will look in for
|
||||
* required files, such as BIOS files and other miscellaneous
|
||||
* system-required files.
|
||||
*/
|
||||
public final class SystemDirActivity extends DirectoryActivity {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.setPathSettingKey("system_directory");
|
||||
super.setIsDirectoryTarget(true);
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
}
|
@ -0,0 +1,371 @@
|
||||
package com.retroarch.browser.dirfragment;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.ListFragment;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ListView;
|
||||
|
||||
import com.retroarch.R;
|
||||
import com.retroarch.browser.FileWrapper;
|
||||
import com.retroarch.browser.IconAdapter;
|
||||
import com.retroarch.browser.preferences.util.UserPreferences;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
|
||||
/**
|
||||
* {@link ListFragment} subclass that provides a file-browser
|
||||
* like UI for browsing for specific files.
|
||||
* <p>
|
||||
* This file browser also allows for custom filtering
|
||||
* depending on the type of class that inherits it.
|
||||
* <p>
|
||||
* This file browser also uses an implementation of a
|
||||
* backstack for remembering previously browsed folders
|
||||
* within this DirectoryFragment.
|
||||
* <p>
|
||||
* To instantiate a new instance of this class
|
||||
* you must use the {@code newInstance} method.
|
||||
*/
|
||||
public final class DirectoryFragment extends DialogFragment
|
||||
{
|
||||
private IconAdapter<FileWrapper> adapter;
|
||||
private File listedDirectory;
|
||||
|
||||
public static final class BackStackItem implements Parcelable
|
||||
{
|
||||
private final String path;
|
||||
private final boolean parentIsBack;
|
||||
|
||||
public BackStackItem(String path, boolean parentIsBack)
|
||||
{
|
||||
this.path = path;
|
||||
this.parentIsBack = parentIsBack;
|
||||
}
|
||||
|
||||
private BackStackItem(Parcel in)
|
||||
{
|
||||
this.path = in.readString();
|
||||
this.parentIsBack = in.readInt() != 0;
|
||||
}
|
||||
|
||||
public int describeContents()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void writeToParcel(Parcel out, int flags)
|
||||
{
|
||||
out.writeString(path);
|
||||
out.writeInt(parentIsBack ? 1 : 0);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<BackStackItem> CREATOR = new Parcelable.Creator<BackStackItem>()
|
||||
{
|
||||
public BackStackItem createFromParcel(Parcel in)
|
||||
{
|
||||
return new BackStackItem(in);
|
||||
}
|
||||
|
||||
public BackStackItem[] newArray(int size)
|
||||
{
|
||||
return new BackStackItem[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener interface for executing ROMs or performing
|
||||
* other things upon the DirectoryFragment instance closing.
|
||||
*/
|
||||
public interface OnDirectoryFragmentClosedListener
|
||||
{
|
||||
/**
|
||||
* Performs some arbitrary action after the
|
||||
* {@link DirectoryFragment} closes.
|
||||
*
|
||||
* @param path The path to the file chosen within the {@link DirectoryFragment}
|
||||
*/
|
||||
void onDirectoryFragmentClosed(String path);
|
||||
}
|
||||
|
||||
|
||||
private ArrayList<BackStackItem> backStack;
|
||||
|
||||
private String startDirectory;
|
||||
private String pathSettingKey;
|
||||
|
||||
public void setStartDirectory(String path)
|
||||
{
|
||||
startDirectory = path;
|
||||
}
|
||||
|
||||
public void setPathSettingKey(String key)
|
||||
{
|
||||
pathSettingKey = key;
|
||||
}
|
||||
|
||||
private boolean isDirectoryTarget;
|
||||
public void setIsDirectoryTarget(boolean enable)
|
||||
{
|
||||
isDirectoryTarget = enable;
|
||||
}
|
||||
|
||||
private OnDirectoryFragmentClosedListener onClosedListener;
|
||||
public void setOnDirectoryFragmentClosedListener(OnDirectoryFragmentClosedListener onClosedListener)
|
||||
{
|
||||
this.onClosedListener = onClosedListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a new instance of a DirectoryFragment
|
||||
* with a title specified by the given resource ID.
|
||||
*
|
||||
* @param titleResId String resource ID for the title
|
||||
* of this DirectoryFragment.
|
||||
*
|
||||
* @return A new instance of a DirectoryFragment.
|
||||
*/
|
||||
public static DirectoryFragment newInstance(int titleResId)
|
||||
{
|
||||
final DirectoryFragment dFrag = new DirectoryFragment();
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putInt("titleResId", titleResId);
|
||||
dFrag.setArguments(bundle);
|
||||
|
||||
return dFrag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
||||
{
|
||||
ListView rootView = (ListView) inflater.inflate(R.layout.line_list, container, false);
|
||||
rootView.setOnItemClickListener(onItemClickListener);
|
||||
|
||||
// Set the dialog title.
|
||||
getDialog().setTitle(getArguments().getInt("titleResId"));
|
||||
|
||||
// Setup the list
|
||||
adapter = new IconAdapter<FileWrapper>(getActivity(), R.layout.line_list_item);
|
||||
rootView.setAdapter(adapter);
|
||||
|
||||
// Load Directory
|
||||
if (savedInstanceState != null)
|
||||
{
|
||||
backStack = savedInstanceState.getParcelableArrayList("BACKSTACK");
|
||||
}
|
||||
|
||||
if (backStack == null || backStack.isEmpty())
|
||||
{
|
||||
backStack = new ArrayList<BackStackItem>();
|
||||
String startPath = (startDirectory == null || startDirectory.isEmpty()) ? Environment
|
||||
.getExternalStorageDirectory().getPath() : startDirectory;
|
||||
backStack.add(new BackStackItem(startPath, false));
|
||||
}
|
||||
|
||||
wrapFiles();
|
||||
return rootView;
|
||||
}
|
||||
|
||||
private final OnItemClickListener onItemClickListener = new OnItemClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
|
||||
{
|
||||
final FileWrapper item = adapter.getItem(position);
|
||||
|
||||
if (item.isParentItem() && backStack.get(backStack.size() - 1).parentIsBack)
|
||||
{
|
||||
backStack.remove(backStack.size() - 1);
|
||||
wrapFiles();
|
||||
return;
|
||||
}
|
||||
else if (item.isDirSelectItem())
|
||||
{
|
||||
finishWithPath(listedDirectory.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
|
||||
final File selected = item.isParentItem() ? listedDirectory.getParentFile() : item.getFile();
|
||||
|
||||
if (selected.isDirectory())
|
||||
{
|
||||
backStack.add(new BackStackItem(selected.getAbsolutePath(), !item.isParentItem()));
|
||||
wrapFiles();
|
||||
}
|
||||
else
|
||||
{
|
||||
String filePath = selected.getAbsolutePath();
|
||||
finishWithPath(filePath);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState)
|
||||
{
|
||||
super.onSaveInstanceState(outState);
|
||||
|
||||
outState.putParcelableArrayList("BACKSTACK", backStack);
|
||||
}
|
||||
|
||||
private void finishWithPath(String path)
|
||||
{
|
||||
if (pathSettingKey != null && !pathSettingKey.isEmpty())
|
||||
{
|
||||
SharedPreferences settings = UserPreferences.getPreferences(getActivity());
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.putString(pathSettingKey, path);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
if (onClosedListener != null)
|
||||
{
|
||||
onClosedListener.onDirectoryFragmentClosed(path);
|
||||
}
|
||||
|
||||
dismiss();
|
||||
}
|
||||
|
||||
// TODO: Hook this up to a callable interface (if backstack is desirable).
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event)
|
||||
{
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK)
|
||||
{
|
||||
if (backStack.size() > 1)
|
||||
{
|
||||
backStack.remove(backStack.size() - 1);
|
||||
wrapFiles();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private ArrayList<String> allowedExt;
|
||||
private ArrayList<String> disallowedExt;
|
||||
|
||||
private boolean filterPath(String path)
|
||||
{
|
||||
if (disallowedExt != null)
|
||||
{
|
||||
for (String ext : disallowedExt)
|
||||
{
|
||||
if (path.endsWith(ext))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (allowedExt != null)
|
||||
{
|
||||
for (String ext : allowedExt)
|
||||
{
|
||||
if (path.endsWith(ext))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows specifying an allowed file extension.
|
||||
* <p>
|
||||
* Any files that contain this file extension will be shown
|
||||
* within the DirectoryFragment file browser. Those that don't
|
||||
* contain this extension will not be shows.
|
||||
* <p>
|
||||
* It is possible to specify more than one allowed extension by
|
||||
* simply calling this method with a different file extension specified.
|
||||
*
|
||||
* @param ext The file extension(s) to allow being shown in this DirectoryFragment.
|
||||
*/
|
||||
public void addAllowedExts(String... exts)
|
||||
{
|
||||
if (allowedExt == null)
|
||||
allowedExt = new ArrayList<String>();
|
||||
|
||||
allowedExt.addAll(Arrays.asList(exts));
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows specifying a disallowed file extension.
|
||||
* <p>
|
||||
* Any files that contain this file extension will not be shown
|
||||
* within the DirectoryFragment file browser.
|
||||
* <p>
|
||||
* It is possible to specify more than one disallowed extension by
|
||||
* simply calling this method with a different file extension specified.
|
||||
*
|
||||
* @param exts The file extension(s) to hide from being shown in this DirectoryFragment.
|
||||
*/
|
||||
public void addDisallowedExts(String... exts)
|
||||
{
|
||||
if (disallowedExt == null)
|
||||
disallowedExt = new ArrayList<String>();
|
||||
|
||||
disallowedExt.addAll(Arrays.asList(exts));
|
||||
}
|
||||
|
||||
private void wrapFiles()
|
||||
{
|
||||
listedDirectory = new File(backStack.get(backStack.size() - 1).path);
|
||||
|
||||
if (!listedDirectory.isDirectory())
|
||||
{
|
||||
throw new IllegalArgumentException("Directory is not valid.");
|
||||
}
|
||||
|
||||
adapter.clear();
|
||||
|
||||
if (isDirectoryTarget)
|
||||
adapter.add(new FileWrapper(null, FileWrapper.DIRSELECT, true));
|
||||
|
||||
if (listedDirectory.getParentFile() != null)
|
||||
adapter.add(new FileWrapper(null, FileWrapper.PARENT, true));
|
||||
|
||||
// Copy new items
|
||||
final File[] files = listedDirectory.listFiles();
|
||||
if (files != null)
|
||||
{
|
||||
for (File file : files)
|
||||
{
|
||||
String path = file.getName();
|
||||
|
||||
boolean allowFile = file.isDirectory() || (filterPath(path) && !isDirectoryTarget);
|
||||
if (allowFile)
|
||||
{
|
||||
adapter.add(new FileWrapper(file, FileWrapper.FILE, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort items
|
||||
adapter.sort(new Comparator<FileWrapper>()
|
||||
{
|
||||
@Override
|
||||
public int compare(FileWrapper left, FileWrapper right)
|
||||
{
|
||||
return left.compareTo(right);
|
||||
};
|
||||
});
|
||||
|
||||
// Update
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package com.retroarch.browser.mainmenu;
|
||||
|
||||
import com.retroarch.R;
|
||||
import com.retroarch.browser.preferences.util.UserPreferences;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
|
||||
/**
|
||||
* {@link PreferenceActivity} subclass that provides all of the
|
||||
* functionality of the main menu screen.
|
||||
*/
|
||||
public final class MainMenuActivity extends FragmentActivity
|
||||
{
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Load the main menu layout
|
||||
setContentView(R.layout.mainmenu_activity_layout);
|
||||
if (savedInstanceState == null)
|
||||
{
|
||||
final MainMenuFragment mmf = new MainMenuFragment();
|
||||
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
|
||||
|
||||
// Add the base main menu fragment to the content view.
|
||||
ft.replace(R.id.content_frame, mmf);
|
||||
ft.commit();
|
||||
}
|
||||
|
||||
// Bind audio stream to hardware controls.
|
||||
setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||
}
|
||||
|
||||
public void setModule(String core_path, String core_name)
|
||||
{
|
||||
UserPreferences.updateConfigFile(this);
|
||||
|
||||
SharedPreferences prefs = UserPreferences.getPreferences(this);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("libretro_path", core_path);
|
||||
edit.putString("libretro_name", core_name);
|
||||
edit.commit();
|
||||
|
||||
// Set the title section to contain the name of the selected core.
|
||||
setCoreTitle(core_name);
|
||||
}
|
||||
|
||||
public void setCoreTitle(String core_name)
|
||||
{
|
||||
setTitle("RetroArch : " + core_name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle data)
|
||||
{
|
||||
super.onSaveInstanceState(data);
|
||||
|
||||
data.putCharSequence("title", getTitle());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Bundle savedInstanceState)
|
||||
{
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
|
||||
setTitle(savedInstanceState.getCharSequence("title"));
|
||||
}
|
||||
}
|
@ -0,0 +1,416 @@
|
||||
package com.retroarch.browser.mainmenu;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.preference.Preference;
|
||||
import android.preference.Preference.OnPreferenceClickListener;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.retroarch.R;
|
||||
import com.retroarch.browser.CoreSelection;
|
||||
import com.retroarch.browser.HistorySelection;
|
||||
import com.retroarch.browser.ModuleWrapper;
|
||||
import com.retroarch.browser.NativeInterface;
|
||||
import com.retroarch.browser.RetroActivity;
|
||||
import com.retroarch.browser.dirfragment.DirectoryFragment;
|
||||
import com.retroarch.browser.dirfragment.DirectoryFragment.OnDirectoryFragmentClosedListener;
|
||||
import com.retroarch.browser.preferences.fragments.util.PreferenceListFragment;
|
||||
import com.retroarch.browser.preferences.util.UserPreferences;
|
||||
|
||||
/**
|
||||
* Represents the fragment that handles the layout of the main menu.
|
||||
*/
|
||||
public final class MainMenuFragment extends PreferenceListFragment implements OnPreferenceClickListener, OnDirectoryFragmentClosedListener
|
||||
{
|
||||
private static final String TAG = "MainMenuFragment";
|
||||
private Context ctx;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Cache the context
|
||||
this.ctx = getActivity();
|
||||
|
||||
// Add the layout through the XML.
|
||||
addPreferencesFromResource(R.xml.main_menu);
|
||||
|
||||
// Set the listeners for the menu items
|
||||
findPreference("loadCorePref").setOnPreferenceClickListener(this);
|
||||
findPreference("loadRomPref").setOnPreferenceClickListener(this);
|
||||
findPreference("loadRomHistoryPref").setOnPreferenceClickListener(this);
|
||||
|
||||
// Extract assets.
|
||||
extractAssets();
|
||||
|
||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
||||
if (!prefs.getBoolean("first_time_refreshrate_calculate", false))
|
||||
{
|
||||
prefs.edit().putBoolean("first_time_refreshrate_calculate", true).commit();
|
||||
|
||||
if (!detectDevice(false))
|
||||
{
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(ctx)
|
||||
.setTitle(R.string.welcome_to_retroarch)
|
||||
.setMessage(R.string.welcome_to_retroarch_desc)
|
||||
.setPositiveButton(R.string.ok, null);
|
||||
alert.show();
|
||||
}
|
||||
|
||||
showGPLWaiver();
|
||||
}
|
||||
}
|
||||
|
||||
private void showGPLWaiver()
|
||||
{
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(getActivity())
|
||||
.setTitle(R.string.gpl_waiver)
|
||||
.setMessage(R.string.gpl_waiver_desc)
|
||||
.setPositiveButton(R.string.keep_cores, null)
|
||||
.setNegativeButton(R.string.remove_cores, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
final File[] libs = new File(getActivity().getApplicationInfo().dataDir, "/cores").listFiles();
|
||||
for (final File lib : libs)
|
||||
{
|
||||
ModuleWrapper module = new ModuleWrapper(getActivity().getApplicationContext(), lib);
|
||||
|
||||
boolean gplv3 = module.getCoreLicense().equals("GPLv3");
|
||||
boolean gplv2 = module.getCoreLicense().equals("GPLv2");
|
||||
|
||||
if (!gplv3 && !gplv2)
|
||||
{
|
||||
String libName = lib.getName();
|
||||
Log.i("GPL WAIVER", "Deleting non-GPL core" + libName + "...");
|
||||
lib.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
alert.show();
|
||||
}
|
||||
|
||||
private void extractAssets()
|
||||
{
|
||||
if (areAssetsExtracted())
|
||||
return;
|
||||
|
||||
final Dialog dialog = new Dialog(ctx);
|
||||
final Handler handler = new Handler();
|
||||
dialog.setContentView(R.layout.assets);
|
||||
dialog.setCancelable(false);
|
||||
dialog.setTitle(R.string.asset_extraction);
|
||||
|
||||
// Java is fun :)
|
||||
Thread assetsThread = new Thread(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
extractAssetsThread();
|
||||
handler.post(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
assetsThread.start();
|
||||
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
// Extract assets from native code. Doing it from Java side is apparently unbearably slow ...
|
||||
private void extractAssetsThread()
|
||||
{
|
||||
try
|
||||
{
|
||||
final String dataDir = ctx.getApplicationInfo().dataDir;
|
||||
final String apk = ctx.getApplicationInfo().sourceDir;
|
||||
|
||||
Log.i(TAG, "Extracting RetroArch assets from: " + apk + " ...");
|
||||
boolean success = NativeInterface.extractArchiveTo(apk, "assets", dataDir);
|
||||
if (!success) {
|
||||
throw new IOException("Failed to extract assets ...");
|
||||
}
|
||||
Log.i(TAG, "Extracted assets ...");
|
||||
|
||||
File cacheVersion = new File(dataDir, ".cacheversion");
|
||||
DataOutputStream outputCacheVersion = new DataOutputStream(new FileOutputStream(cacheVersion, false));
|
||||
outputCacheVersion.writeInt(getVersionCode());
|
||||
outputCacheVersion.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
Log.e(TAG, "Failed to extract assets to cache.");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean areAssetsExtracted()
|
||||
{
|
||||
int version = getVersionCode();
|
||||
|
||||
try
|
||||
{
|
||||
String dataDir = ctx.getApplicationInfo().dataDir;
|
||||
File cacheVersion = new File(dataDir, ".cacheversion");
|
||||
if (cacheVersion.isFile() && cacheVersion.canRead() && cacheVersion.canWrite())
|
||||
{
|
||||
DataInputStream cacheStream = new DataInputStream(new FileInputStream(cacheVersion));
|
||||
int currentCacheVersion = 0;
|
||||
try
|
||||
{
|
||||
currentCacheVersion = cacheStream.readInt();
|
||||
cacheStream.close();
|
||||
}
|
||||
catch (IOException ignored)
|
||||
{
|
||||
}
|
||||
|
||||
if (currentCacheVersion == version)
|
||||
{
|
||||
Log.i("ASSETS", "Assets already extracted, skipping...");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
Log.e(TAG, "Failed to extract assets to cache.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private int getVersionCode()
|
||||
{
|
||||
int version = 0;
|
||||
try
|
||||
{
|
||||
version = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0).versionCode;
|
||||
}
|
||||
catch (NameNotFoundException ignored)
|
||||
{
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
private boolean detectDevice(boolean show_dialog)
|
||||
{
|
||||
boolean retval = false;
|
||||
|
||||
final boolean mentionPlayStore = !Build.MODEL.equals("OUYA Console");
|
||||
final int messageId = (mentionPlayStore ? R.string.detect_device_msg_general : R.string.detect_device_msg_ouya);
|
||||
|
||||
Log.i("Device MODEL", Build.MODEL);
|
||||
if (Build.MODEL.equals("SHIELD"))
|
||||
{
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(ctx);
|
||||
alert.setTitle(R.string.nvidia_shield_detected);
|
||||
alert.setMessage(messageId);
|
||||
alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
SharedPreferences prefs = UserPreferences.getPreferences(ctx);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("video_refresh_rate", Double.toString(60.00d));
|
||||
edit.putBoolean("input_overlay_enable", false);
|
||||
edit.putBoolean("input_autodetect_enable", true);
|
||||
edit.putString("audio_latency", "64");
|
||||
edit.putBoolean("audio_latency_auto", true);
|
||||
edit.commit();
|
||||
UserPreferences.updateConfigFile(ctx);
|
||||
}
|
||||
});
|
||||
alert.show();
|
||||
retval = true;
|
||||
}
|
||||
else if (Build.MODEL.equals("GAMEMID_BT"))
|
||||
{
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(ctx);
|
||||
alert.setTitle(R.string.game_mid_detected);
|
||||
alert.setMessage(messageId);
|
||||
alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
SharedPreferences prefs = UserPreferences.getPreferences(ctx);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("input_overlay_enable", false);
|
||||
edit.putBoolean("input_autodetect_enable", true);
|
||||
edit.putString("audio_latency", "160");
|
||||
edit.putBoolean("audio_latency_auto", false);
|
||||
edit.commit();
|
||||
UserPreferences.updateConfigFile(ctx);
|
||||
}
|
||||
});
|
||||
alert.show();
|
||||
retval = true;
|
||||
}
|
||||
else if (Build.MODEL.equals("OUYA Console"))
|
||||
{
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(ctx);
|
||||
alert.setTitle(R.string.ouya_detected);
|
||||
alert.setMessage(messageId);
|
||||
alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
SharedPreferences prefs = UserPreferences.getPreferences(ctx);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("input_overlay_enable", false);
|
||||
edit.putBoolean("input_autodetect_enable", true);
|
||||
edit.putString("audio_latency", "64");
|
||||
edit.putBoolean("audio_latency_auto", true);
|
||||
edit.commit();
|
||||
UserPreferences.updateConfigFile(ctx);
|
||||
}
|
||||
});
|
||||
alert.show();
|
||||
retval = true;
|
||||
}
|
||||
else if (Build.MODEL.equals("R800x"))
|
||||
{
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(ctx);
|
||||
alert.setTitle(R.string.xperia_play_detected);
|
||||
alert.setMessage(messageId);
|
||||
alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
SharedPreferences prefs = UserPreferences.getPreferences(ctx);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("video_threaded", false);
|
||||
edit.putBoolean("input_overlay_enable", false);
|
||||
edit.putBoolean("input_autodetect_enable", true);
|
||||
edit.putString("video_refresh_rate", Double.toString(59.19132938771038));
|
||||
edit.putString("audio_latency", "128");
|
||||
edit.putBoolean("audio_latency_auto", false);
|
||||
edit.commit();
|
||||
UserPreferences.updateConfigFile(ctx);
|
||||
}
|
||||
});
|
||||
alert.show();
|
||||
retval = true;
|
||||
}
|
||||
else if (Build.ID.equals("JSS15J"))
|
||||
{
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(ctx);
|
||||
alert.setTitle(R.string.nexus_7_2013_detected);
|
||||
alert.setMessage(messageId);
|
||||
alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
SharedPreferences prefs = UserPreferences.getPreferences(ctx);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("video_refresh_rate", Double.toString(59.65));
|
||||
edit.putString("audio_latency", "64");
|
||||
edit.putBoolean("audio_latency_auto", false);
|
||||
edit.commit();
|
||||
UserPreferences.updateConfigFile(ctx);
|
||||
}
|
||||
});
|
||||
alert.show();
|
||||
retval = true;
|
||||
}
|
||||
|
||||
if (show_dialog)
|
||||
{
|
||||
Toast.makeText(ctx, R.string.no_optimal_settings, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference)
|
||||
{
|
||||
final String prefKey = preference.getKey();
|
||||
|
||||
// Load Core Preference
|
||||
if (prefKey.equals("loadCorePref"))
|
||||
{
|
||||
final CoreSelection coreSelection = new CoreSelection();
|
||||
coreSelection.show(getFragmentManager(), "core_selection");
|
||||
}
|
||||
// Load ROM Preference
|
||||
else if (prefKey.equals("loadRomPref"))
|
||||
{
|
||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
||||
final String libretro_path = prefs.getString("libretro_path", ctx.getApplicationInfo().dataDir + "/cores");
|
||||
|
||||
if (!new File(libretro_path).isDirectory())
|
||||
{
|
||||
final DirectoryFragment romBrowser = DirectoryFragment.newInstance(R.string.load_game);
|
||||
romBrowser.addDisallowedExts(".state", ".srm", ".state.auto", ".rtc");
|
||||
romBrowser.setOnDirectoryFragmentClosedListener(this);
|
||||
|
||||
final String startPath = prefs.getString("rgui_browser_directory", "");
|
||||
if (!startPath.isEmpty() && new File(startPath).exists())
|
||||
romBrowser.setStartDirectory(startPath);
|
||||
|
||||
romBrowser.show(getFragmentManager(), "romBrowser");
|
||||
}
|
||||
else
|
||||
{
|
||||
Toast.makeText(ctx, R.string.load_a_core_first, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
// Load ROM (History) Preference
|
||||
else if (prefKey.equals("loadRomHistoryPref"))
|
||||
{
|
||||
final HistorySelection historySelection = new HistorySelection();
|
||||
historySelection.show(getFragmentManager(), "history_selection");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDirectoryFragmentClosed(String path)
|
||||
{
|
||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
||||
final String libretro_path = prefs.getString("libretro_path", "");
|
||||
|
||||
UserPreferences.updateConfigFile(ctx);
|
||||
String current_ime = Settings.Secure.getString(ctx.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
|
||||
Toast.makeText(ctx, String.format(getString(R.string.loading_data), path), Toast.LENGTH_SHORT).show();
|
||||
Intent myIntent = new Intent(ctx, RetroActivity.class);
|
||||
myIntent.putExtra("ROM", path);
|
||||
myIntent.putExtra("LIBRETRO", libretro_path);
|
||||
myIntent.putExtra("CONFIGFILE", UserPreferences.getDefaultConfigPath(ctx));
|
||||
myIntent.putExtra("IME", current_ime);
|
||||
startActivity(myIntent);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.retroarch.browser.preferences.fragments;
|
||||
package com.retroarch.browser.preferences;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
@ -15,6 +15,11 @@ import android.support.v7.app.ActionBar.TabListener;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
|
||||
import com.retroarch.R;
|
||||
import com.retroarch.browser.preferences.fragments.AudioPreferenceFragment;
|
||||
import com.retroarch.browser.preferences.fragments.GeneralPreferenceFragment;
|
||||
import com.retroarch.browser.preferences.fragments.InputPreferenceFragment;
|
||||
import com.retroarch.browser.preferences.fragments.PathPreferenceFragment;
|
||||
import com.retroarch.browser.preferences.fragments.VideoPreferenceFragment;
|
||||
import com.retroarch.browser.preferences.fragments.util.PreferenceListFragment;
|
||||
import com.retroarch.browser.preferences.util.UserPreferences;
|
||||
|
@ -1,6 +1,9 @@
|
||||
package com.retroarch.browser.preferences.fragments;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.retroarch.R;
|
||||
import com.retroarch.browser.dirfragment.DirectoryFragment;
|
||||
import com.retroarch.browser.preferences.fragments.util.PreferenceListFragment;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
@ -14,7 +17,7 @@ import android.view.inputmethod.InputMethodManager;
|
||||
/**
|
||||
* A {@link PreferenceListFragment} responsible for handling the input preferences.
|
||||
*/
|
||||
public final class InputPreferenceFragment extends PreferenceListFragment
|
||||
public final class InputPreferenceFragment extends PreferenceListFragment implements OnPreferenceClickListener
|
||||
{
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
@ -24,26 +27,26 @@ public final class InputPreferenceFragment extends PreferenceListFragment
|
||||
// Add input preferences from the XML.
|
||||
addPreferencesFromResource(R.xml.input_preferences);
|
||||
|
||||
// Set Input Method preference
|
||||
final Preference setImePref = findPreference("set_ime_pref");
|
||||
setImePref.setOnPreferenceClickListener(new OnPreferenceClickListener()
|
||||
{
|
||||
// Set preference listeners
|
||||
findPreference("set_ime_pref").setOnPreferenceClickListener(this);
|
||||
findPreference("report_ime_pref").setOnPreferenceClickListener(this);
|
||||
findPreference("inputOverlayDirPref").setOnPreferenceClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference)
|
||||
{
|
||||
final String prefKey = preference.getKey();
|
||||
|
||||
// Set Input Method preference
|
||||
if (prefKey.equals("set_ime_pref"))
|
||||
{
|
||||
// Show an IME picker so the user can change their set IME.
|
||||
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.showInputMethodPicker();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Report IME preference
|
||||
final Preference reportImePref = findPreference("report_ime_pref");
|
||||
reportImePref.setOnPreferenceClickListener(new OnPreferenceClickListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference)
|
||||
else if (prefKey.equals("report_ime_pref"))
|
||||
{
|
||||
final String currentIme = Settings.Secure.getString(getActivity().getContentResolver(),
|
||||
Settings.Secure.DEFAULT_INPUT_METHOD);
|
||||
@ -53,8 +56,20 @@ public final class InputPreferenceFragment extends PreferenceListFragment
|
||||
reportImeDialog.setMessage(currentIme);
|
||||
reportImeDialog.setNegativeButton(R.string.close, null);
|
||||
reportImeDialog.show();
|
||||
}
|
||||
// Input Overlay selection
|
||||
else if (prefKey.equals("inputOverlayDirPref"))
|
||||
{
|
||||
final DirectoryFragment overlayBrowser = DirectoryFragment.newInstance(R.string.input_overlay_select);
|
||||
File overlayDir = new File(getActivity().getApplicationInfo().dataDir, "overlays");
|
||||
if (overlayDir.exists())
|
||||
overlayBrowser.setStartDirectory(overlayDir.getAbsolutePath());
|
||||
|
||||
overlayBrowser.addAllowedExts(".cfg");
|
||||
overlayBrowser.setPathSettingKey("input_overlay");
|
||||
overlayBrowser.show(getFragmentManager(), "overlayBrowser");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,17 @@
|
||||
package com.retroarch.browser.preferences.fragments;
|
||||
|
||||
import com.retroarch.R;
|
||||
import com.retroarch.browser.dirfragment.DirectoryFragment;
|
||||
import com.retroarch.browser.preferences.fragments.util.PreferenceListFragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.preference.Preference;
|
||||
import android.preference.Preference.OnPreferenceClickListener;
|
||||
|
||||
/**
|
||||
* A {@link PreferenceListFragment} that handles the path preferences.
|
||||
*/
|
||||
public final class PathPreferenceFragment extends PreferenceListFragment
|
||||
public final class PathPreferenceFragment extends PreferenceListFragment implements OnPreferenceClickListener
|
||||
{
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
@ -17,5 +20,52 @@ public final class PathPreferenceFragment extends PreferenceListFragment
|
||||
|
||||
// Add path preferences from the XML.
|
||||
addPreferencesFromResource(R.xml.path_preferences);
|
||||
|
||||
// Set preference click listeners
|
||||
findPreference("romDirPref").setOnPreferenceClickListener(this);
|
||||
findPreference("srmDirPref").setOnPreferenceClickListener(this);
|
||||
findPreference("saveStateDirPref").setOnPreferenceClickListener(this);
|
||||
findPreference("systemDirPref").setOnPreferenceClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference)
|
||||
{
|
||||
final String prefKey = preference.getKey();
|
||||
|
||||
// Custom ROM directory
|
||||
if (prefKey.equals("romDirPref"))
|
||||
{
|
||||
final DirectoryFragment romDirBrowser = DirectoryFragment.newInstance(R.string.rom_directory_select);
|
||||
romDirBrowser.setPathSettingKey("rgui_browser_directory");
|
||||
romDirBrowser.setIsDirectoryTarget(true);
|
||||
romDirBrowser.show(getFragmentManager(), "romDirBrowser");
|
||||
}
|
||||
// Custom savefile directory
|
||||
else if (prefKey.equals("srmDirPref"))
|
||||
{
|
||||
final DirectoryFragment srmDirBrowser = DirectoryFragment.newInstance(R.string.savefile_directory_select);
|
||||
srmDirBrowser.setPathSettingKey("savefile_directory");
|
||||
srmDirBrowser.setIsDirectoryTarget(true);
|
||||
srmDirBrowser.show(getFragmentManager(), "srmDirBrowser");
|
||||
}
|
||||
// Custom save state directory
|
||||
else if (prefKey.equals("saveStateDirPref"))
|
||||
{
|
||||
final DirectoryFragment saveStateDirBrowser = DirectoryFragment.newInstance(R.string.save_state_directory_select);
|
||||
saveStateDirBrowser.setPathSettingKey("savestate_directory");
|
||||
saveStateDirBrowser.setIsDirectoryTarget(true);
|
||||
saveStateDirBrowser.show(getFragmentManager(), "saveStateDirBrowser");
|
||||
}
|
||||
// Custom system directory
|
||||
else if (prefKey.equals("systemDirPref"))
|
||||
{
|
||||
final DirectoryFragment systemDirBrowser = DirectoryFragment.newInstance(R.string.system_directory_select);
|
||||
systemDirBrowser.setPathSettingKey("system_directory");
|
||||
systemDirBrowser.setIsDirectoryTarget(true);
|
||||
systemDirBrowser.show(getFragmentManager(), "systemDirBrowser");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package com.retroarch.browser.preferences.fragments;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.retroarch.R;
|
||||
import com.retroarch.browser.dirfragment.DirectoryFragment;
|
||||
import com.retroarch.browser.preferences.fragments.util.PreferenceListFragment;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
@ -15,7 +18,7 @@ import android.widget.Toast;
|
||||
/**
|
||||
* A {@link PreferenceListFragment} responsible for handling the video preferences.
|
||||
*/
|
||||
public final class VideoPreferenceFragment extends PreferenceListFragment
|
||||
public final class VideoPreferenceFragment extends PreferenceListFragment implements OnPreferenceClickListener
|
||||
{
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
@ -25,12 +28,18 @@ public final class VideoPreferenceFragment extends PreferenceListFragment
|
||||
// Add preferences from the resources
|
||||
addPreferencesFromResource(R.xml.video_preferences);
|
||||
|
||||
// Set OS-reported refresh rate preference.
|
||||
final Preference osReportedRatePref = findPreference("set_os_reported_ref_rate_pref");
|
||||
osReportedRatePref.setOnPreferenceClickListener(new OnPreferenceClickListener()
|
||||
{
|
||||
// Set preference click listeners
|
||||
findPreference("set_os_reported_ref_rate_pref").setOnPreferenceClickListener(this);
|
||||
findPreference("glsl_shader_pref").setOnPreferenceClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference)
|
||||
{
|
||||
final String prefKey = preference.getKey();
|
||||
|
||||
// Set OS-reported refresh rate preference.
|
||||
if (prefKey.equals("set_os_reported_ref_rate_pref"))
|
||||
{
|
||||
final WindowManager wm = getActivity().getWindowManager();
|
||||
final Display display = wm.getDefaultDisplay();
|
||||
@ -42,8 +51,21 @@ public final class VideoPreferenceFragment extends PreferenceListFragment
|
||||
edit.commit();
|
||||
|
||||
Toast.makeText(getActivity(), String.format(getString(R.string.using_os_reported_refresh_rate), rate), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
// GLSL shader selection
|
||||
else if (prefKey.equals("glsl_shader_pref"))
|
||||
{
|
||||
final DirectoryFragment shaderBrowser = DirectoryFragment.newInstance(R.string.glsl_shader_select);
|
||||
|
||||
File shaderDir = new File(getActivity().getApplicationInfo().dataDir, "shaders_glsl");
|
||||
if (shaderDir.exists())
|
||||
shaderBrowser.setStartDirectory(shaderDir.getAbsolutePath());
|
||||
|
||||
shaderBrowser.addAllowedExts(".glsl");
|
||||
shaderBrowser.setPathSettingKey("video_shader");
|
||||
shaderBrowser.show(getFragmentManager(), "shaderBrowser");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +1,43 @@
|
||||
package com.retroarch.browser.preferences.fragments.util;
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
package com.retroarch.browser.preferences.fragments.util;
|
||||
|
||||
import com.retroarch.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceGroup;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.support.v4.app.ListFragment;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnKeyListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ListView;
|
||||
|
||||
public class PreferenceListFragment extends ListFragment
|
||||
public abstract class PreferenceListFragment extends Fragment implements PreferenceManagerCompat.OnPreferenceTreeClickListener
|
||||
{
|
||||
private static final String PREFERENCES_TAG = "android:preferences";
|
||||
|
||||
private PreferenceManager mPreferenceManager;
|
||||
private ListView mList;
|
||||
private boolean mHavePrefs;
|
||||
@ -34,7 +49,7 @@ public class PreferenceListFragment extends ListFragment
|
||||
private static final int FIRST_REQUEST_CODE = 100;
|
||||
|
||||
private static final int MSG_BIND_PREFERENCES = 1;
|
||||
private final Handler mHandler = new Handler()
|
||||
private Handler mHandler = new Handler()
|
||||
{
|
||||
@Override
|
||||
public void handleMessage(Message msg)
|
||||
@ -48,35 +63,42 @@ public class PreferenceListFragment extends ListFragment
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable mRequestFocus = new Runnable()
|
||||
final private Runnable mRequestFocus = new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mList.focusableViewAvailable(mList);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle b)
|
||||
/**
|
||||
* Interface that PreferenceFragment's containing activity should
|
||||
* implement to be able to process preference items that wish to
|
||||
* switch to a new fragment.
|
||||
*/
|
||||
public interface OnPreferenceStartFragmentCallback
|
||||
{
|
||||
View view = inflater.inflate(R.layout.preference_list_content, container, false);
|
||||
view.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
|
||||
|
||||
return view;
|
||||
/**
|
||||
* Called when the user has clicked on a Preference that has
|
||||
* a fragment class name associated with it. The implementation
|
||||
* to should instantiate and switch to an instance of the given
|
||||
* fragment.
|
||||
*/
|
||||
boolean onPreferenceStartFragment(PreferenceListFragment caller, Preference pref);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView()
|
||||
public void onCreate(Bundle paramBundle)
|
||||
{
|
||||
super.onDestroyView();
|
||||
super.onCreate(paramBundle);
|
||||
mPreferenceManager = PreferenceManagerCompat.newInstance(getActivity(), FIRST_REQUEST_CODE);
|
||||
PreferenceManagerCompat.setFragment(mPreferenceManager, this);
|
||||
}
|
||||
|
||||
// Kill the list
|
||||
mList = null;
|
||||
|
||||
// Remove callbacks and messages.
|
||||
mHandler.removeCallbacks(mRequestFocus);
|
||||
mHandler.removeMessages(MSG_BIND_PREFERENCES);
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater paramLayoutInflater, ViewGroup paramViewGroup, Bundle paramBundle)
|
||||
{
|
||||
return paramLayoutInflater.inflate(R.layout.preference_list_fragment, paramViewGroup, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -84,12 +106,10 @@ public class PreferenceListFragment extends ListFragment
|
||||
{
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
if (mHavePrefs)
|
||||
{
|
||||
if (mHavePrefs) {
|
||||
bindPreferences();
|
||||
}
|
||||
|
||||
// Done initializing.
|
||||
mInitDone = true;
|
||||
|
||||
if (savedInstanceState != null)
|
||||
@ -107,47 +127,34 @@ public class PreferenceListFragment extends ListFragment
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
public void onStart()
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mPreferenceManager = onCreatePreferenceManager();
|
||||
|
||||
postBindPreferences();
|
||||
super.onStart();
|
||||
PreferenceManagerCompat.setOnPreferenceTreeClickListener(mPreferenceManager, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop()
|
||||
{
|
||||
super.onStop();
|
||||
PreferenceManagerCompat.dispatchActivityStop(mPreferenceManager);
|
||||
PreferenceManagerCompat.setOnPreferenceTreeClickListener(mPreferenceManager, null);
|
||||
}
|
||||
|
||||
try
|
||||
@Override
|
||||
public void onDestroyView()
|
||||
{
|
||||
Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityStop");
|
||||
m.setAccessible(true);
|
||||
m.invoke(mPreferenceManager);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
mList = null;
|
||||
mHandler.removeCallbacks(mRequestFocus);
|
||||
mHandler.removeMessages(MSG_BIND_PREFERENCES);
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy()
|
||||
{
|
||||
super.onDestroy();
|
||||
|
||||
try
|
||||
{
|
||||
Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityDestroy");
|
||||
m.setAccessible(true);
|
||||
m.invoke(mPreferenceManager);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
PreferenceManagerCompat.dispatchActivityDestroy(mPreferenceManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -169,69 +176,12 @@ public class PreferenceListFragment extends ListFragment
|
||||
{
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
try
|
||||
{
|
||||
Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityResult", int.class, int.class, Intent.class);
|
||||
m.setAccessible(true);
|
||||
m.invoke(mPreferenceManager, requestCode, resultCode, data);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
PreferenceManagerCompat.dispatchActivityResult(mPreferenceManager, requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts a message to bind the preferences to the list view.
|
||||
* <p>
|
||||
* Binding late is preferred as any custom preference types created in
|
||||
* {@link #onCreate(Bundle)} are able to have their views recycled.
|
||||
*/
|
||||
private void postBindPreferences()
|
||||
{
|
||||
if (mHandler.hasMessages(MSG_BIND_PREFERENCES))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget();
|
||||
}
|
||||
|
||||
private void bindPreferences()
|
||||
{
|
||||
final PreferenceScreen preferenceScreen = getPreferenceScreen();
|
||||
if (preferenceScreen != null)
|
||||
{
|
||||
preferenceScreen.bind(getListView());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the {@link PreferenceManager}.
|
||||
*
|
||||
* @return The {@link PreferenceManager} used by this fragment.
|
||||
*/
|
||||
private PreferenceManager onCreatePreferenceManager()
|
||||
{
|
||||
try
|
||||
{
|
||||
Constructor<PreferenceManager> c = PreferenceManager.class.getDeclaredConstructor(Activity.class, int.class);
|
||||
c.setAccessible(true);
|
||||
|
||||
PreferenceManager preferenceManager = c.newInstance(getActivity(), FIRST_REQUEST_CODE);
|
||||
return preferenceManager;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link PreferenceManager} used by this fragment.
|
||||
*
|
||||
* @return The {@link PreferenceManager} used by this fragment.
|
||||
* Returns the {@link PreferenceManager} used by this fragment.
|
||||
* @return The {@link PreferenceManager}.
|
||||
*/
|
||||
public PreferenceManager getPreferenceManager()
|
||||
{
|
||||
@ -245,12 +195,7 @@ public class PreferenceListFragment extends ListFragment
|
||||
*/
|
||||
public void setPreferenceScreen(PreferenceScreen preferenceScreen)
|
||||
{
|
||||
try
|
||||
{
|
||||
Method m = PreferenceManager.class.getDeclaredMethod("setPreferences", PreferenceScreen.class);
|
||||
m.setAccessible(true);
|
||||
boolean result = (Boolean) m.invoke(mPreferenceManager, preferenceScreen);
|
||||
if (result && preferenceScreen != null)
|
||||
if (PreferenceManagerCompat.setPreferences(mPreferenceManager, preferenceScreen) && preferenceScreen != null)
|
||||
{
|
||||
mHavePrefs = true;
|
||||
if (mInitDone)
|
||||
@ -259,11 +204,6 @@ public class PreferenceListFragment extends ListFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the root of the preference hierarchy that this fragment is showing.
|
||||
@ -273,17 +213,7 @@ public class PreferenceListFragment extends ListFragment
|
||||
*/
|
||||
public PreferenceScreen getPreferenceScreen()
|
||||
{
|
||||
try
|
||||
{
|
||||
Method m = PreferenceManager.class.getDeclaredMethod("getPreferenceScreen");
|
||||
m.setAccessible(true);
|
||||
return (PreferenceScreen) m.invoke(mPreferenceManager);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return PreferenceManagerCompat.getPreferenceScreen(mPreferenceManager);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -293,7 +223,9 @@ public class PreferenceListFragment extends ListFragment
|
||||
*/
|
||||
public void addPreferencesFromIntent(Intent intent)
|
||||
{
|
||||
throw new UnsupportedOperationException("addPreferencesFromIntent not implemented yet.");
|
||||
requirePreferenceManager();
|
||||
|
||||
setPreferenceScreen(PreferenceManagerCompat.inflateFromIntent(mPreferenceManager, intent, getPreferenceScreen()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -304,26 +236,29 @@ public class PreferenceListFragment extends ListFragment
|
||||
*/
|
||||
public void addPreferencesFromResource(int preferencesResId)
|
||||
{
|
||||
try
|
||||
{
|
||||
Method m = PreferenceManager.class.getDeclaredMethod("inflateFromResource", Context.class, int.class, PreferenceScreen.class);
|
||||
m.setAccessible(true);
|
||||
PreferenceScreen prefScreen = (PreferenceScreen) m.invoke(mPreferenceManager, getActivity(), preferencesResId, getPreferenceScreen());
|
||||
setPreferenceScreen(prefScreen);
|
||||
requirePreferenceManager();
|
||||
|
||||
setPreferenceScreen(PreferenceManagerCompat.inflateFromResource(mPreferenceManager, getActivity(),
|
||||
preferencesResId, getPreferenceScreen()));
|
||||
}
|
||||
catch(Exception e)
|
||||
|
||||
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)
|
||||
{
|
||||
e.printStackTrace();
|
||||
//if (preference.getFragment() != null &&
|
||||
if (getActivity() instanceof OnPreferenceStartFragmentCallback)
|
||||
{
|
||||
return ((OnPreferenceStartFragmentCallback)getActivity()).onPreferenceStartFragment(
|
||||
this, preference);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a {@link Preference} based on its key.
|
||||
*
|
||||
* @param key The key of the preference to retrieve.
|
||||
*
|
||||
* @return The {@link Preference} with the key, or null.
|
||||
*
|
||||
* @see PreferenceGroup#findPreference(CharSequence)
|
||||
*/
|
||||
public Preference findPreference(CharSequence key)
|
||||
@ -336,6 +271,29 @@ public class PreferenceListFragment extends ListFragment
|
||||
return mPreferenceManager.findPreference(key);
|
||||
}
|
||||
|
||||
private void requirePreferenceManager()
|
||||
{
|
||||
if (mPreferenceManager == null)
|
||||
{
|
||||
throw new RuntimeException("This should be called after super.onCreate.");
|
||||
}
|
||||
}
|
||||
|
||||
private void postBindPreferences()
|
||||
{
|
||||
if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return;
|
||||
mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget();
|
||||
}
|
||||
|
||||
private void bindPreferences()
|
||||
{
|
||||
final PreferenceScreen preferenceScreen = getPreferenceScreen();
|
||||
if (preferenceScreen != null)
|
||||
{
|
||||
preferenceScreen.bind(getListView());
|
||||
}
|
||||
}
|
||||
|
||||
public ListView getListView()
|
||||
{
|
||||
ensureList();
|
||||
@ -349,24 +307,45 @@ public class PreferenceListFragment extends ListFragment
|
||||
return;
|
||||
}
|
||||
|
||||
final View root = getView();
|
||||
View root = getView();
|
||||
if (root == null)
|
||||
{
|
||||
throw new IllegalStateException("Content view not yet created");
|
||||
}
|
||||
|
||||
final View rawListView = root.findViewById(android.R.id.list);
|
||||
View rawListView = root.findViewById(android.R.id.list);
|
||||
if (!(rawListView instanceof ListView))
|
||||
{
|
||||
throw new RuntimeException("Content has view with id attribute 'android.R.id.list' that is not a ListView class");
|
||||
throw new RuntimeException(
|
||||
"Content has view with id attribute 'android.R.id.list' that is not a ListView class");
|
||||
}
|
||||
|
||||
mList = (ListView)rawListView;
|
||||
if (mList == null)
|
||||
{
|
||||
throw new RuntimeException("Your content must have a ListView whose id attribute is 'android.R.id.list'");
|
||||
throw new RuntimeException(
|
||||
"Your content must have a ListView whose id attribute is 'android.R.id.list'");
|
||||
}
|
||||
|
||||
mList.setOnKeyListener(mListOnKeyListener);
|
||||
mHandler.post(mRequestFocus);
|
||||
}
|
||||
|
||||
private OnKeyListener mListOnKeyListener = new OnKeyListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event)
|
||||
{
|
||||
Object selectedItem = mList.getSelectedItem();
|
||||
if (selectedItem instanceof Preference)
|
||||
{
|
||||
@SuppressWarnings("unused")
|
||||
View selectedView = mList.getSelectedView();
|
||||
//return ((Preference)selectedItem).onKey(
|
||||
// selectedView, keyCode, event);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.retroarch.browser.preferences.fragments.util;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.util.Log;
|
||||
|
||||
class PreferenceManagerCompat
|
||||
{
|
||||
private static final String TAG = PreferenceManagerCompat.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* Interface definition for a callback to be invoked when a
|
||||
* {@link Preference} in the hierarchy rooted at this {@link PreferenceScreen} is
|
||||
* clicked.
|
||||
*/
|
||||
interface OnPreferenceTreeClickListener
|
||||
{
|
||||
/**
|
||||
* Called when a preference in the tree rooted at this
|
||||
* {@link PreferenceScreen} has been clicked.
|
||||
*
|
||||
* @param preferenceScreen The {@link PreferenceScreen} that the
|
||||
* preference is located in.
|
||||
* @param preference The preference that was clicked.
|
||||
* @return Whether the click was handled.
|
||||
*/
|
||||
boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference);
|
||||
}
|
||||
|
||||
static PreferenceManager newInstance(Activity activity, int firstRequestCode)
|
||||
{
|
||||
try
|
||||
{
|
||||
Constructor<PreferenceManager> c = PreferenceManager.class.getDeclaredConstructor(Activity.class, int.class);
|
||||
c.setAccessible(true);
|
||||
return c.newInstance(activity, firstRequestCode);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.w(TAG, "Couldn't call constructor PreferenceManager by reflection", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the owning preference fragment
|
||||
*/
|
||||
static void setFragment(PreferenceManager manager, PreferenceListFragment fragment)
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the callback to be invoked when a {@link Preference} in the
|
||||
* hierarchy rooted at this {@link PreferenceManager} is clicked.
|
||||
*
|
||||
* @param listener The callback to be invoked.
|
||||
*/
|
||||
static void setOnPreferenceTreeClickListener(PreferenceManager manager, final OnPreferenceTreeClickListener listener)
|
||||
{
|
||||
try
|
||||
{
|
||||
Field onPreferenceTreeClickListener = PreferenceManager.class.getDeclaredField("mOnPreferenceTreeClickListener");
|
||||
onPreferenceTreeClickListener.setAccessible(true);
|
||||
if (listener != null)
|
||||
{
|
||||
Object proxy = Proxy.newProxyInstance(onPreferenceTreeClickListener.getType().getClassLoader(), new Class[] { onPreferenceTreeClickListener.getType() }, new InvocationHandler()
|
||||
{
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args)
|
||||
{
|
||||
if (method.getName().equals("onPreferenceTreeClick"))
|
||||
{
|
||||
return Boolean.valueOf(listener.onPreferenceTreeClick((PreferenceScreen) args[0], (Preference) args[1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
onPreferenceTreeClickListener.set(manager, proxy);
|
||||
}
|
||||
else
|
||||
{
|
||||
onPreferenceTreeClickListener.set(manager, null);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.w(TAG, "Couldn't set PreferenceManager.mOnPreferenceTreeClickListener by reflection", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inflates a preference hierarchy from the preference hierarchies of
|
||||
* {@link Activity Activities} that match the given {@link Intent}. An
|
||||
* {@link Activity} defines its preference hierarchy with meta-data using
|
||||
* the {@link #METADATA_KEY_PREFERENCES} key.
|
||||
* <p>
|
||||
* If a preference hierarchy is given, the new preference hierarchies will
|
||||
* be merged in.
|
||||
*
|
||||
* @param queryIntent The intent to match activities.
|
||||
* @param rootPreferences Optional existing hierarchy to merge the new
|
||||
* hierarchies into.
|
||||
* @return The root hierarchy (if one was not provided, the new hierarchy's
|
||||
* root).
|
||||
*/
|
||||
static PreferenceScreen inflateFromIntent(PreferenceManager manager, Intent intent, PreferenceScreen screen)
|
||||
{
|
||||
try
|
||||
{
|
||||
Method m = PreferenceManager.class.getDeclaredMethod("inflateFromIntent", Intent.class, PreferenceScreen.class);
|
||||
m.setAccessible(true);
|
||||
PreferenceScreen prefScreen = (PreferenceScreen) m.invoke(manager, intent, screen);
|
||||
return prefScreen;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.w(TAG, "Couldn't call PreferenceManager.inflateFromIntent by reflection", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inflates a preference hierarchy from XML. If a preference hierarchy is
|
||||
* given, the new preference hierarchies will be merged in.
|
||||
*
|
||||
* @param context The context of the resource.
|
||||
* @param resId The resource ID of the XML to inflate.
|
||||
* @param rootPreferences Optional existing hierarchy to merge the new
|
||||
* hierarchies into.
|
||||
* @return The root hierarchy (if one was not provided, the new hierarchy's
|
||||
* root).
|
||||
* @hide
|
||||
*/
|
||||
static PreferenceScreen inflateFromResource(PreferenceManager manager, Activity activity, int resId, PreferenceScreen screen)
|
||||
{
|
||||
try
|
||||
{
|
||||
Method m = PreferenceManager.class.getDeclaredMethod("inflateFromResource", Context.class, int.class, PreferenceScreen.class);
|
||||
m.setAccessible(true);
|
||||
PreferenceScreen prefScreen = (PreferenceScreen) m.invoke(manager, activity, resId, screen);
|
||||
return prefScreen;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.w(TAG, "Couldn't call PreferenceManager.inflateFromResource by reflection", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the root of the preference hierarchy managed by this class.
|
||||
*
|
||||
* @return The {@link PreferenceScreen} object that is at the root of the hierarchy.
|
||||
*/
|
||||
static PreferenceScreen getPreferenceScreen(PreferenceManager manager)
|
||||
{
|
||||
try
|
||||
{
|
||||
Method m = PreferenceManager.class.getDeclaredMethod("getPreferenceScreen");
|
||||
m.setAccessible(true);
|
||||
return (PreferenceScreen) m.invoke(manager);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.w(TAG, "Couldn't call PreferenceManager.getPreferenceScreen by reflection", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the {@link PreferenceManager} to dispatch a subactivity result.
|
||||
*/
|
||||
static void dispatchActivityResult(PreferenceManager manager, int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
try
|
||||
{
|
||||
Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityResult", int.class, int.class, Intent.class);
|
||||
m.setAccessible(true);
|
||||
m.invoke(manager, requestCode, resultCode, data);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.w(TAG, "Couldn't call PreferenceManager.dispatchActivityResult by reflection", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the {@link PreferenceManager} to dispatch the activity stop
|
||||
* event.
|
||||
*/
|
||||
static void dispatchActivityStop(PreferenceManager manager)
|
||||
{
|
||||
try
|
||||
{
|
||||
Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityStop");
|
||||
m.setAccessible(true);
|
||||
m.invoke(manager);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.w(TAG, "Couldn't call PreferenceManager.dispatchActivityStop by reflection", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the {@link PreferenceManager} to dispatch the activity destroy
|
||||
* event.
|
||||
*/
|
||||
static void dispatchActivityDestroy(PreferenceManager manager)
|
||||
{
|
||||
try
|
||||
{
|
||||
Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityDestroy");
|
||||
m.setAccessible(true);
|
||||
m.invoke(manager);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.w(TAG, "Couldn't call PreferenceManager.dispatchActivityDestroy by reflection", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the root of the preference hierarchy.
|
||||
*
|
||||
* @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy.
|
||||
* @return Whether the {@link PreferenceScreen} given is different than the previous.
|
||||
*/
|
||||
static boolean setPreferences(PreferenceManager manager, PreferenceScreen screen)
|
||||
{
|
||||
try
|
||||
{
|
||||
Method m = PreferenceManager.class.getDeclaredMethod("setPreferences", PreferenceScreen.class);
|
||||
m.setAccessible(true);
|
||||
return ((Boolean) m.invoke(manager, screen));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.w(TAG, "Couldn't call PreferenceManager.setPreferences by reflection", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user