mirror of
https://github.com/libretro/RetroArch
synced 2025-02-21 09:39:56 +00:00
[Android] Add an info view to the core manager InstalledCoresFragment. Also added a dual-fragment layout of this for tablet devices as well.
This commit is contained in:
parent
cb1381c94f
commit
48fd723015
@ -25,7 +25,6 @@
|
|||||||
<category android:name="tv.ouya.intent.category.GAME" />
|
<category android:name="tv.ouya.intent.category.GAME" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name="com.retroarch.browser.HelpActivity"/>
|
|
||||||
<activity android:name="com.retroarch.browser.FileWrapper"/>
|
<activity android:name="com.retroarch.browser.FileWrapper"/>
|
||||||
<activity android:name="com.retroarch.browser.RetroTVMode"/>
|
<activity android:name="com.retroarch.browser.RetroTVMode"/>
|
||||||
|
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:baselineAligned="false"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content" >
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:id="@+id/installed_cores_fragment_container1"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:id="@+id/installed_cores_fragment_container2"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -0,0 +1,7 @@
|
|||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:id="@+id/installed_cores_fragment_container1"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
|
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:background="?android:attr/activatedBackgroundIndicator"
|
||||||
|
android:choiceMode="singleChoice"
|
||||||
android:id="@android:id/list"
|
android:id="@android:id/list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
<string name="load_core">Load Core</string>
|
<string name="load_core">Load Core</string>
|
||||||
<string name="load_game">Load Game</string>
|
<string name="load_game">Load Game</string>
|
||||||
<string name="load_game_history">Load Game (History)</string>
|
<string name="load_game_history">Load Game (History)</string>
|
||||||
<string name="manage_cores">Manage Cores</string>
|
|
||||||
<string name="settings">Settings</string>
|
<string name="settings">Settings</string>
|
||||||
<string name="help">Help</string>
|
<string name="help">Help</string>
|
||||||
<string name="about">About</string>
|
<string name="about">About</string>
|
||||||
@ -33,6 +32,14 @@
|
|||||||
<string name="uninstall_success">Successfully uninstalled core: %1$s.</string>
|
<string name="uninstall_success">Successfully uninstalled core: %1$s.</string>
|
||||||
<string name="downloadable_cores">Downloadable Cores</string>
|
<string name="downloadable_cores">Downloadable Cores</string>
|
||||||
|
|
||||||
|
<!-- Core Manager Info Fragment -->
|
||||||
|
<string name="core_info_displayNameTitle">Display Name</string>
|
||||||
|
<string name="core_info_internalNameTitle">Internal Name</string>
|
||||||
|
<string name="core_info_systemNameTitle">Emulated Systems</string>
|
||||||
|
<string name="core_info_emu_author">Emulator Authors</string>
|
||||||
|
<string name="core_info_licenseTitle">Core License</string>
|
||||||
|
<string name="core_info_manufacterer">Manufacturer</string>
|
||||||
|
|
||||||
<!-- Display Refresh Rate Test Class -->
|
<!-- Display Refresh Rate Test Class -->
|
||||||
<string name="refresh_rate_calibration">Refresh rate calibration</string>
|
<string name="refresh_rate_calibration">Refresh rate calibration</string>
|
||||||
<string name="touch_screen_with_fingers">Touch the screen with your fingers for more accurate measurements.</string>
|
<string name="touch_screen_with_fingers">Touch the screen with your fingers for more accurate measurements.</string>
|
||||||
@ -51,7 +58,7 @@
|
|||||||
<string name="welcome_to_retroarch">Welcome to RetroArch</string>
|
<string name="welcome_to_retroarch">Welcome to RetroArch</string>
|
||||||
<string name="welcome_to_retroarch_desc">This is your first time starting up RetroArch. RetroArch will now be preconfigured for the best possible gameplay experience.</string>
|
<string name="welcome_to_retroarch_desc">This is your first time starting up RetroArch. RetroArch will now be preconfigured for the best possible gameplay experience.</string>
|
||||||
<string name="gpl_waiver">GPL waiver</string>
|
<string name="gpl_waiver">GPL waiver</string>
|
||||||
<string name="gpl_waiver_desc">Copyright (C) 2010-2013 RetroArch Team.\n\nThis program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License along with this program; if not, see www.gnu.org/licenses.\n\nAdditional permission under GNU GPL version 3 section 7\n\nIf you modify this Program, or any covered work, by linking or combining it with any non-GPL libretro core, containing parts covered by the terms of the core\'s license, the licensors of this Program grant you additional permission to convey the resulting work.</string>
|
<string name="gpl_waiver_desc">Copyright © 2010–2013 RetroArch Team.\n\nThis program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License along with this program; if not, see www.gnu.org/licenses.\n\nAdditional permission under GNU GPL version 3 section 7\n\nIf you modify this Program, or any covered work, by linking or combining it with any non-GPL libretro core, containing parts covered by the terms of the core\'s license, the licensors of this Program grant you additional permission to convey the resulting work.</string>
|
||||||
<string name="detect_device_msg_ouya">The ideal configuration options for your device will now be preconfigured.\n\nNOTE: For optimal performance, turn off Google Account sync, GPS and Wi-Fi in your Android settings menu.</string>
|
<string name="detect_device_msg_ouya">The ideal configuration options for your device will now be preconfigured.\n\nNOTE: For optimal performance, turn off Google Account sync, GPS and Wi-Fi in your Android settings menu.</string>
|
||||||
<string name="detect_device_msg_general">The ideal configuration options for your device will now be preconfigured.\n\nNOTE: For optimal performance, turn off Google Account sync, Google Play Store auto-updates, GPS and Wi-Fi in your Android settings menu.</string>
|
<string name="detect_device_msg_general">The ideal configuration options for your device will now be preconfigured.\n\nNOTE: For optimal performance, turn off Google Account sync, Google Play Store auto-updates, GPS and Wi-Fi in your Android settings menu.</string>
|
||||||
<string name="nvidia_shield_detected">NVidia Shield detected</string>
|
<string name="nvidia_shield_detected">NVidia Shield detected</string>
|
||||||
|
@ -22,6 +22,7 @@ public final class ModuleWrapper implements IconAdapterItem, Comparable<ModuleWr
|
|||||||
private final String manufacturer;
|
private final String manufacturer;
|
||||||
private final String systemName;
|
private final String systemName;
|
||||||
private final String license;
|
private final String license;
|
||||||
|
private final List<String> authors;
|
||||||
private final List<String> supportedExtensions;
|
private final List<String> supportedExtensions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,29 +55,40 @@ public final class ModuleWrapper implements IconAdapterItem, Comparable<ModuleWr
|
|||||||
final ConfigFile infoFile = new ConfigFile(infoFilePath);
|
final ConfigFile infoFile = new ConfigFile(infoFilePath);
|
||||||
|
|
||||||
// Now read info out of the info file. Make them an empty string if the key doesn't exist.
|
// Now read info out of the info file. Make them an empty string if the key doesn't exist.
|
||||||
this.displayName = (infoFile.keyExists("display_name")) ? infoFile.getString("display_name") : "";
|
this.displayName = (infoFile.keyExists("display_name")) ? infoFile.getString("display_name") : "N/A";
|
||||||
this.coreName = (infoFile.keyExists("corename")) ? infoFile.getString("corename") : "";
|
this.coreName = (infoFile.keyExists("corename")) ? infoFile.getString("corename") : "N/A";
|
||||||
this.systemName = (infoFile.keyExists("systemname")) ? infoFile.getString("systemname") : "";
|
this.systemName = (infoFile.keyExists("systemname")) ? infoFile.getString("systemname") : "N/A";
|
||||||
this.manufacturer = (infoFile.keyExists("manufacturer")) ? infoFile.getString("manufacturer") : "";
|
this.manufacturer = (infoFile.keyExists("manufacturer")) ? infoFile.getString("manufacturer") : "N/A";
|
||||||
this.license = (infoFile.keyExists("license")) ? infoFile.getString("license") : "";
|
this.license = (infoFile.keyExists("license")) ? infoFile.getString("license") : "N/A";
|
||||||
|
|
||||||
// Getting supported extensions is a little different.
|
// Getting supported extensions and authors is a little different.
|
||||||
// We need to split at every '|' character, since it is
|
// We need to split at every '|' character, since it is
|
||||||
// the delimiter for a new extension that the core supports.
|
// the delimiter for a new extension that the core supports.
|
||||||
//
|
//
|
||||||
// Cores that don't have multiple extensions supported
|
// Cores that don't have multiple extensions supported
|
||||||
// don't contain the '|' delimiter, so we just create a String array with
|
// don't contain the '|' delimiter, so we just create a String list
|
||||||
// a size of 1, and just directly assign the retrieved extensions to it.
|
// and just directly assign the retrieved extensions to it.
|
||||||
final String supportedExts = infoFile.getString("supported_extensions");
|
final String supportedExts = infoFile.getString("supported_extensions");
|
||||||
if (supportedExts != null && supportedExts.contains("|"))
|
if (supportedExts != null && supportedExts.contains("|"))
|
||||||
{
|
{
|
||||||
this.supportedExtensions = new ArrayList<String>(Arrays.asList(supportedExts.split("|")));
|
this.supportedExtensions = new ArrayList<String>(Arrays.asList(supportedExts.split("\\|")));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.supportedExtensions = new ArrayList<String>();
|
this.supportedExtensions = new ArrayList<String>();
|
||||||
this.supportedExtensions.add(supportedExts);
|
this.supportedExtensions.add(supportedExts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final String emuAuthors = infoFile.getString("authors");
|
||||||
|
if (emuAuthors != null && emuAuthors.contains("|"))
|
||||||
|
{
|
||||||
|
this.authors = new ArrayList<String>(Arrays.asList(emuAuthors.split("\\|")));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.authors = new ArrayList<String>();
|
||||||
|
this.authors.add(emuAuthors);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else // No info file.
|
else // No info file.
|
||||||
{
|
{
|
||||||
@ -84,6 +96,7 @@ public final class ModuleWrapper implements IconAdapterItem, Comparable<ModuleWr
|
|||||||
this.systemName = "N/A";
|
this.systemName = "N/A";
|
||||||
this.manufacturer = "N/A";
|
this.manufacturer = "N/A";
|
||||||
this.license = "N/A";
|
this.license = "N/A";
|
||||||
|
this.authors = new ArrayList<String>();
|
||||||
this.supportedExtensions = new ArrayList<String>();
|
this.supportedExtensions = new ArrayList<String>();
|
||||||
this.coreName = coreName;
|
this.coreName = coreName;
|
||||||
}
|
}
|
||||||
@ -109,6 +122,26 @@ public final class ModuleWrapper implements IconAdapterItem, Comparable<ModuleWr
|
|||||||
return displayName;
|
return displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the internal core name for this wrapped core.
|
||||||
|
*
|
||||||
|
* @return the internal core name for this wrapped core.
|
||||||
|
*/
|
||||||
|
public String getInternalName()
|
||||||
|
{
|
||||||
|
return coreName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name of the system that is emulated by this wrapped core.
|
||||||
|
*
|
||||||
|
* @return the name of the system that is emulated by this wrapped core.
|
||||||
|
*/
|
||||||
|
public String getEmulatedSystemName()
|
||||||
|
{
|
||||||
|
return systemName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the license that this core is protected under.
|
* Gets the license that this core is protected under.
|
||||||
*
|
*
|
||||||
@ -131,6 +164,16 @@ public final class ModuleWrapper implements IconAdapterItem, Comparable<ModuleWr
|
|||||||
return manufacturer;
|
return manufacturer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of authors of this emulator core.
|
||||||
|
*
|
||||||
|
* @return the list of authors of this emulator core.
|
||||||
|
*/
|
||||||
|
public List<String> getEmulatorAuthors()
|
||||||
|
{
|
||||||
|
return authors;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the List of supported extensions for this core.
|
* Gets the List of supported extensions for this core.
|
||||||
*
|
*
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package com.retroarch.browser.coremanager;
|
package com.retroarch.browser.coremanager;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.retroarch.R;
|
import com.retroarch.R;
|
||||||
import com.retroarch.browser.coremanager.fragments.DownloadableCoresFragment;
|
import com.retroarch.browser.coremanager.fragments.DownloadableCoresFragment;
|
||||||
import com.retroarch.browser.coremanager.fragments.InstalledCoresFragment;
|
import com.retroarch.browser.coremanager.fragments.InstalledCoresManagerFragment;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
@ -75,6 +77,52 @@ public final class CoreManagerActivity extends ActionBarActivity implements TabL
|
|||||||
// Do nothing. Not used.
|
// Do nothing. Not used.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed()
|
||||||
|
{
|
||||||
|
if (!returnBackStackImmediate(getSupportFragmentManager()))
|
||||||
|
{
|
||||||
|
super.onBackPressed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HACK: Propagate back button press to child fragments.
|
||||||
|
// This might not work properly when you have multiple fragments
|
||||||
|
// adding multiple children to the backstack. (in our case, only
|
||||||
|
// one child fragments adds fragments to the backstack, so we're fine with this).
|
||||||
|
//
|
||||||
|
// Congrats to Google for having a bugged backstack that doesn't account for
|
||||||
|
// nested fragments. A heavy applause to them for the immense stupidity if this is
|
||||||
|
// actually intended behavior. This is why overriding the handling of back presses
|
||||||
|
// should be present in Fragments.
|
||||||
|
//
|
||||||
|
// Taken from: http://android.joao.jp/2013/09/back-stack-with-nested-fragments-back.html
|
||||||
|
// If you ever read this, thank you very much for making the workaround.
|
||||||
|
//
|
||||||
|
private boolean returnBackStackImmediate(FragmentManager fm)
|
||||||
|
{
|
||||||
|
List<Fragment> fragments = fm.getFragments();
|
||||||
|
if (fragments != null && fragments.size() > 0)
|
||||||
|
{
|
||||||
|
for (Fragment fragment : fragments)
|
||||||
|
{
|
||||||
|
if (fragment.getChildFragmentManager().getBackStackEntryCount() > 0)
|
||||||
|
{
|
||||||
|
if (fragment.getChildFragmentManager().popBackStackImmediate())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return returnBackStackImmediate(fragment.getChildFragmentManager());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Adapter for the core manager ViewPager.
|
// Adapter for the core manager ViewPager.
|
||||||
private final class ViewPagerAdapter extends FragmentPagerAdapter
|
private final class ViewPagerAdapter extends FragmentPagerAdapter
|
||||||
{
|
{
|
||||||
@ -94,7 +142,7 @@ public final class CoreManagerActivity extends ActionBarActivity implements TabL
|
|||||||
switch (position)
|
switch (position)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return new InstalledCoresFragment();
|
return new InstalledCoresManagerFragment();
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
return new DownloadableCoresFragment();
|
return new DownloadableCoresFragment();
|
||||||
|
@ -4,9 +4,9 @@ import android.support.v4.app.ListFragment;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ListFragment} that is responsible for showing
|
* {@link ListFragment} that is responsible for showing
|
||||||
* cores that are able to be downloaded or are not installed..
|
* cores that are able to be downloaded or are not installed.
|
||||||
*/
|
*/
|
||||||
public final class DownloadableCoresFragment extends ListFragment
|
public final class DownloadableCoresFragment extends ListFragment
|
||||||
{
|
{
|
||||||
|
// TODO: Implement.
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,120 @@
|
|||||||
|
package com.retroarch.browser.coremanager.fragments;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import com.retroarch.R;
|
||||||
|
import com.retroarch.browser.ModuleWrapper;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.ListFragment;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fragment that displays information about a selected core.
|
||||||
|
*/
|
||||||
|
public final class InstalledCoreInfoFragment extends ListFragment
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Creates a new instance of a InstalledCoreInfoFragment.
|
||||||
|
*
|
||||||
|
* @param core The wrapped core to represent.
|
||||||
|
*
|
||||||
|
* @return a new instance of a InstalledCoreInfoFragment.
|
||||||
|
*/
|
||||||
|
public static InstalledCoreInfoFragment newInstance(ModuleWrapper core)
|
||||||
|
{
|
||||||
|
InstalledCoreInfoFragment cif = new InstalledCoreInfoFragment();
|
||||||
|
|
||||||
|
// Set the core path as an argument.
|
||||||
|
// This will allow us to re-retrieve information if the Fragment
|
||||||
|
// is destroyed upon state changes
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putString("core_path", core.getUnderlyingFile().getPath());
|
||||||
|
cif.setArguments(args);
|
||||||
|
|
||||||
|
return cif;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
// Inflate the view.
|
||||||
|
ListView infoView = (ListView) inflater.inflate(R.layout.coremanager_listview, container, false);
|
||||||
|
|
||||||
|
// Get the appropriate info providers.
|
||||||
|
final Bundle args = getArguments();
|
||||||
|
final ModuleWrapper core = new ModuleWrapper(getActivity(), new File(args.getString("core_path")));
|
||||||
|
|
||||||
|
// Initialize the core info.
|
||||||
|
CoreInfoAdapter adapter = new CoreInfoAdapter(getActivity(), android.R.layout.simple_list_item_2);
|
||||||
|
adapter.add(new InstalledCoreInfoItem(getString(R.string.core_info_displayNameTitle), core.getDisplayName()));
|
||||||
|
adapter.add(new InstalledCoreInfoItem(getString(R.string.core_info_internalNameTitle), core.getInternalName()));
|
||||||
|
adapter.add(new InstalledCoreInfoItem(getString(R.string.core_info_systemNameTitle), core.getEmulatedSystemName()));
|
||||||
|
adapter.add(new InstalledCoreInfoItem(getString(R.string.core_info_manufacterer), core.getManufacturer()));
|
||||||
|
adapter.add(new InstalledCoreInfoItem(getString(R.string.core_info_emu_author), core.getEmulatorAuthors()));
|
||||||
|
adapter.add(new InstalledCoreInfoItem(getString(R.string.core_info_licenseTitle), core.getCoreLicense()));
|
||||||
|
|
||||||
|
// Set the list adapter.
|
||||||
|
infoView.setAdapter(adapter);
|
||||||
|
|
||||||
|
return infoView;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapter backing this InstalledCoreInfoFragment
|
||||||
|
*/
|
||||||
|
private final class CoreInfoAdapter extends ArrayAdapter<InstalledCoreInfoItem>
|
||||||
|
{
|
||||||
|
private final Context context;
|
||||||
|
private final int resourceId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param context The current {@link Context}.
|
||||||
|
* @param resourceId The resource ID for a layout file containing a layout to use when instantiating views.
|
||||||
|
*/
|
||||||
|
public CoreInfoAdapter(Context context, int resourceId)
|
||||||
|
{
|
||||||
|
super(context, resourceId);
|
||||||
|
|
||||||
|
this.context = context;
|
||||||
|
this.resourceId = resourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent)
|
||||||
|
{
|
||||||
|
if (convertView == null)
|
||||||
|
{
|
||||||
|
LayoutInflater vi = LayoutInflater.from(context);
|
||||||
|
convertView = vi.inflate(resourceId, parent, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
final InstalledCoreInfoItem item = getItem(position);
|
||||||
|
if (item != null)
|
||||||
|
{
|
||||||
|
final TextView title = (TextView) convertView.findViewById(android.R.id.text1);
|
||||||
|
final TextView subtitle = (TextView) convertView.findViewById(android.R.id.text2);
|
||||||
|
|
||||||
|
if (title != null)
|
||||||
|
{
|
||||||
|
title.setText(item.getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subtitle != null)
|
||||||
|
{
|
||||||
|
subtitle.setText(item.getSubtitle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return convertView;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package com.retroarch.browser.coremanager.fragments;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a single list item within the InstalledCoreInfoFragment.
|
||||||
|
*/
|
||||||
|
public final class InstalledCoreInfoItem
|
||||||
|
{
|
||||||
|
private final String title;
|
||||||
|
private final String subtitle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param title Title of the item within the core info list.
|
||||||
|
* @param subtitle Subtitle of the item within the core info list.
|
||||||
|
*/
|
||||||
|
public InstalledCoreInfoItem(String title, String subtitle)
|
||||||
|
{
|
||||||
|
this.title = title;
|
||||||
|
this.subtitle = subtitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* <p>
|
||||||
|
* Allows for creating a subtitle out of multiple strings.
|
||||||
|
*
|
||||||
|
* @param title Title of the item within the core info list.
|
||||||
|
* @param subtitle List of strings to add to the subtitle section of this item.
|
||||||
|
*/
|
||||||
|
public InstalledCoreInfoItem(String title, List<String> subtitle)
|
||||||
|
{
|
||||||
|
this.title = title;
|
||||||
|
this.subtitle = TextUtils.join(", ", subtitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title of this InstalledCoreInfoItem.
|
||||||
|
*
|
||||||
|
* @return the title of this InstalledCoreInfoItem.
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the subtitle of this InstalledCoreInfoItem.
|
||||||
|
*
|
||||||
|
* @return the subtitle of this InstalledCoreInfoItem.
|
||||||
|
*/
|
||||||
|
public String getSubtitle()
|
||||||
|
{
|
||||||
|
return subtitle;
|
||||||
|
}
|
||||||
|
}
|
@ -21,23 +21,51 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.AdapterView.OnItemLongClickListener;
|
import android.widget.AdapterView.OnItemLongClickListener;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ListFragment} that displays all of the currently installed cores
|
* {@link ListFragment} that displays all of the currently installed cores
|
||||||
|
* <p>
|
||||||
|
* In terms of layout, this is the fragment that is placed on the
|
||||||
|
* left side of the screen within the core manager
|
||||||
*/
|
*/
|
||||||
public final class InstalledCoresFragment extends ListFragment
|
public final class InstalledCoresFragment extends ListFragment
|
||||||
{
|
{
|
||||||
|
// Callback for the interface.
|
||||||
|
private OnCoreItemClickedListener callback;
|
||||||
|
|
||||||
// Adapter backing this ListFragment.
|
// Adapter backing this ListFragment.
|
||||||
private InstalledCoresAdapter adapter;
|
private InstalledCoresAdapter adapter;
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public void onCreate(Bundle savedInstanceState)
|
* Interface that a parent fragment must implement
|
||||||
|
* in order to display the core info view.
|
||||||
|
*/
|
||||||
|
interface OnCoreItemClickedListener
|
||||||
{
|
{
|
||||||
super.onCreate(savedInstanceState);
|
/**
|
||||||
|
* The action to perform when a core is selected within the list view.
|
||||||
|
*
|
||||||
|
* @param position The position of the item in the list.
|
||||||
|
* @param core A reference to the actual {@link ModuleWrapper}
|
||||||
|
* represented by that list item.
|
||||||
|
*/
|
||||||
|
void onCoreItemClicked(int position, ModuleWrapper core);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
// Inflate the layout for this ListFragment.
|
||||||
|
ListView parentView = (ListView) inflater.inflate(R.layout.coremanager_listview, container, false);
|
||||||
|
|
||||||
|
// Set the long click listener.
|
||||||
|
parentView.setOnItemLongClickListener(itemLongClickListener);
|
||||||
|
|
||||||
|
// Get the callback. (implemented within InstalledCoresManagerFragment).
|
||||||
|
callback = (OnCoreItemClickedListener) getParentFragment();
|
||||||
|
|
||||||
// The list of items that will be added to the adapter backing this ListFragment.
|
// The list of items that will be added to the adapter backing this ListFragment.
|
||||||
final List<ModuleWrapper> items = new ArrayList<ModuleWrapper>();
|
final List<ModuleWrapper> items = new ArrayList<ModuleWrapper>();
|
||||||
@ -48,58 +76,59 @@ public final class InstalledCoresFragment extends ListFragment
|
|||||||
|
|
||||||
// Populate the list
|
// Populate the list
|
||||||
final File[] libs = new File(getActivity().getApplicationInfo().dataDir, "/cores").listFiles();
|
final File[] libs = new File(getActivity().getApplicationInfo().dataDir, "/cores").listFiles();
|
||||||
for (File lib : libs)
|
if (libs != null)
|
||||||
{
|
{
|
||||||
String libName = lib.getName();
|
for (File lib : libs)
|
||||||
|
|
||||||
// Never append a NEON lib if we don't have NEON.
|
|
||||||
if (libName.contains("neon") && !supportsNeon)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// If we have a NEON version with NEON capable CPU,
|
|
||||||
// never append a non-NEON version.
|
|
||||||
if (supportsNeon && !libName.contains("neon"))
|
|
||||||
{
|
{
|
||||||
boolean hasNeonVersion = false;
|
String libName = lib.getName();
|
||||||
for (File lib_ : libs)
|
|
||||||
{
|
// Never append a NEON lib if we don't have NEON.
|
||||||
String otherName = lib_.getName();
|
if (libName.contains("neon") && !supportsNeon)
|
||||||
String baseName = libName.replace(".so", "");
|
|
||||||
|
|
||||||
if (otherName.contains("neon") && otherName.startsWith(baseName))
|
|
||||||
{
|
|
||||||
hasNeonVersion = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasNeonVersion)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// If we have a NEON version with NEON capable CPU,
|
||||||
|
// never append a non-NEON version.
|
||||||
|
if (supportsNeon && !libName.contains("neon"))
|
||||||
|
{
|
||||||
|
boolean hasNeonVersion = false;
|
||||||
|
for (File lib_ : libs)
|
||||||
|
{
|
||||||
|
String otherName = lib_.getName();
|
||||||
|
String baseName = libName.replace(".so", "");
|
||||||
|
|
||||||
|
if (otherName.contains("neon") && otherName.startsWith(baseName))
|
||||||
|
{
|
||||||
|
hasNeonVersion = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasNeonVersion)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add it to the list.
|
||||||
|
items.add(new ModuleWrapper(getActivity(), lib));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add it to the list.
|
|
||||||
items.add(new ModuleWrapper(getActivity(), lib));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort the list alphabetically
|
// Sort the list alphabetically
|
||||||
Collections.sort(items);
|
Collections.sort(items);
|
||||||
|
|
||||||
// Initialize and set the backing adapter for this ListFragment.
|
// Initialize and set the backing adapter for this ListFragment.
|
||||||
adapter = new InstalledCoresAdapter(getActivity(), R.layout.coremanager_list_item, items);
|
adapter = new InstalledCoresAdapter(getActivity(), android.R.layout.simple_list_item_2, items);
|
||||||
setListAdapter(adapter);
|
parentView.setAdapter(adapter);
|
||||||
|
|
||||||
|
return parentView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
public void onListItemClick(ListView l, View v, int position, long id)
|
||||||
{
|
{
|
||||||
// Inflate the layout for this ListFragment.
|
callback.onCoreItemClicked(position, adapter.getItem(position));
|
||||||
View parentView = inflater.inflate(R.layout.coremanager_listview, container, false);
|
|
||||||
|
|
||||||
// Set the long click listener.
|
|
||||||
ListView mainList = (ListView) parentView.findViewById(android.R.id.list);
|
|
||||||
mainList.setOnItemLongClickListener(itemLongClickListener);
|
|
||||||
|
|
||||||
return mainList;
|
// Set the item as checked so it highlights in the two-fragment view.
|
||||||
|
getListView().setItemChecked(position, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will be the handler for long clicks on individual list items in this ListFragment.
|
// This will be the handler for long clicks on individual list items in this ListFragment.
|
||||||
@ -181,9 +210,8 @@ public final class InstalledCoresFragment extends ListFragment
|
|||||||
final ModuleWrapper item = items.get(position);
|
final ModuleWrapper item = items.get(position);
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
TextView title = (TextView) convertView.findViewById(R.id.CoreManagerListItemTitle);
|
TextView title = (TextView) convertView.findViewById(android.R.id.text1);
|
||||||
TextView subtitle = (TextView) convertView.findViewById(R.id.CoreManagerListItemSubTitle);
|
TextView subtitle = (TextView) convertView.findViewById(android.R.id.text2);
|
||||||
ImageView icon = (ImageView) convertView.findViewById(R.id.CoreManagerListItemIcon);
|
|
||||||
|
|
||||||
if (title != null)
|
if (title != null)
|
||||||
{
|
{
|
||||||
@ -194,11 +222,6 @@ public final class InstalledCoresFragment extends ListFragment
|
|||||||
{
|
{
|
||||||
subtitle.setText(item.getSubText());
|
subtitle.setText(item.getSubText());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (icon != null)
|
|
||||||
{
|
|
||||||
// TODO: Set core icon.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertView;
|
return convertView;
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
package com.retroarch.browser.coremanager.fragments;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v4.app.FragmentTransaction;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import com.retroarch.R;
|
||||||
|
import com.retroarch.browser.ModuleWrapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Underlying {@link Fragment} that manages layout functionality
|
||||||
|
* for the two fragments that rest inside of this one.
|
||||||
|
*/
|
||||||
|
public class InstalledCoresManagerFragment extends Fragment implements InstalledCoresFragment.OnCoreItemClickedListener
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
View v = inflater.inflate(R.layout.coremanager_installed_cores_base, container, false);
|
||||||
|
|
||||||
|
final Fragment installedCores = new InstalledCoresFragment();
|
||||||
|
final FragmentTransaction ft = getChildFragmentManager().beginTransaction();
|
||||||
|
ft.replace(R.id.installed_cores_fragment_container1, installedCores);
|
||||||
|
ft.commit();
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCoreItemClicked(int position, ModuleWrapper core)
|
||||||
|
{
|
||||||
|
// If this view does not exist, it means the screen
|
||||||
|
// is not considered 'large' and thus, we use the single fragment layout.
|
||||||
|
if (getView().findViewById(R.id.installed_cores_fragment_container2) == null)
|
||||||
|
{
|
||||||
|
InstalledCoreInfoFragment cif = InstalledCoreInfoFragment.newInstance(core);
|
||||||
|
FragmentTransaction ft = getChildFragmentManager().beginTransaction();
|
||||||
|
ft.replace(R.id.installed_cores_fragment_container1, cif);
|
||||||
|
ft.addToBackStack(null);
|
||||||
|
ft.commit();
|
||||||
|
}
|
||||||
|
else // Large screen
|
||||||
|
{
|
||||||
|
InstalledCoreInfoFragment cif = InstalledCoreInfoFragment.newInstance(core);
|
||||||
|
FragmentTransaction ft = getChildFragmentManager().beginTransaction();
|
||||||
|
ft.replace(R.id.installed_cores_fragment_container2, cif);
|
||||||
|
ft.commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user