user plugins back to top + use header categories
This commit is contained in:
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.cradle.iitc_mobile"
|
||||
android:versionCode="45"
|
||||
android:versionName="0.6.1">
|
||||
android:versionCode="46"
|
||||
android:versionName="0.6.2">
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="14"
|
||||
|
40
mobile/res/layout/preference_header_item.xml
Normal file
40
mobile/res/layout/preference_header_item.xml
Normal file
@ -0,0 +1,40 @@
|
||||
<?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="wrap_content"
|
||||
android:background="?android:attr/activatedBackgroundIndicator"
|
||||
android:baselineAligned="false"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="48dp"
|
||||
android:paddingRight="?android:attr/scrollbarSize" >
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="6dip"
|
||||
android:layout_marginLeft="6dip"
|
||||
android:layout_marginRight="6dip"
|
||||
android:layout_marginTop="6dip"
|
||||
android:layout_weight="1" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/plug_pref_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/plug_pref_summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@android:id/title"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
@ -10,4 +10,7 @@
|
||||
|
||||
<dimen name="icon_margin">8dp</dimen>
|
||||
|
||||
<dimen name="header_icon_width">28dp</dimen>
|
||||
|
||||
|
||||
</resources>
|
@ -1,12 +1,20 @@
|
||||
package com.cradle.iitc_mobile;
|
||||
|
||||
import android.app.ActionBar;
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
@ -22,6 +30,16 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity {
|
||||
private List<Header> mHeaders;
|
||||
// we use a tree map to have a map with alphabetical order
|
||||
private static TreeMap<String, ArrayList<IITC_PluginPreference>> sPlugins = null;
|
||||
public static final String USER_PLUGIN = "00000";
|
||||
|
||||
@Override
|
||||
public void setListAdapter(ListAdapter adapter) {
|
||||
if (adapter == null) {
|
||||
super.setListAdapter(null);
|
||||
} else {
|
||||
super.setListAdapter(new HeaderAdapter(this, mHeaders));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBuildHeaders(List<Header> target) {
|
||||
@ -35,6 +53,8 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity {
|
||||
Log.d("iitcm", "opened plugin prefs the first time since app start -> parse plugins");
|
||||
sPlugins = new TreeMap<String, ArrayList<IITC_PluginPreference>>();
|
||||
setUpPluginPreferenceScreen();
|
||||
} else {
|
||||
checkForNewPlugins();
|
||||
}
|
||||
addHeaders();
|
||||
}
|
||||
@ -56,9 +76,7 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity {
|
||||
return sPlugins.get(key);
|
||||
}
|
||||
|
||||
void setUpPluginPreferenceScreen() {
|
||||
|
||||
// get all plugins from asset manager
|
||||
private String[] getAssetPlugins() {
|
||||
AssetManager am = getAssets();
|
||||
String[] asset_array = null;
|
||||
try {
|
||||
@ -67,13 +85,44 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (asset_array == null) {
|
||||
asset_array = new String[0];
|
||||
}
|
||||
return asset_array;
|
||||
}
|
||||
|
||||
private File[] getUserPlugins() {
|
||||
String iitc_path = Environment.getExternalStorageDirectory().getPath()
|
||||
+ "/IITC_Mobile/";
|
||||
File directory = new File(iitc_path + "plugins/");
|
||||
File[] files = directory.listFiles();
|
||||
if (files == null) {
|
||||
files = new File[0];
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
void checkForNewPlugins() {
|
||||
File[] user = getUserPlugins();
|
||||
String[] official = getAssetPlugins();
|
||||
if ((user.length + official.length) != sPlugins.size()) {
|
||||
Log.d("iitcm", "new or less plugins found since last start, rebuild preferences");
|
||||
sPlugins.clear();
|
||||
setUpPluginPreferenceScreen();
|
||||
}
|
||||
}
|
||||
|
||||
void setUpPluginPreferenceScreen() {
|
||||
|
||||
// get all plugins from asset manager
|
||||
String[] asset_array = getAssetPlugins();
|
||||
|
||||
for (String anAsset_array : asset_array) {
|
||||
// find user plugin name for user readable entries
|
||||
Scanner s = null;
|
||||
String src = "";
|
||||
try {
|
||||
s = new Scanner(am.open("plugins/" + anAsset_array))
|
||||
s = new Scanner(getAssets().open("plugins/" + anAsset_array))
|
||||
.useDelimiter("\\A");
|
||||
} catch (IOException e2) {
|
||||
// TODO Auto-generated catch block
|
||||
@ -85,32 +134,27 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity {
|
||||
addPluginPreference(src, anAsset_array, false);
|
||||
}
|
||||
|
||||
// load additional plugins from <storage-path>/IITC_Mobile/plugins/
|
||||
String iitc_path = Environment.getExternalStorageDirectory().getPath()
|
||||
+ "/IITC_Mobile/";
|
||||
File directory = new File(iitc_path + "plugins/");
|
||||
File[] files = directory.listFiles();
|
||||
if (files != null) {
|
||||
// load user plugins from <storage-path>/IITC_Mobile/plugins/
|
||||
File[] files = getUserPlugins();
|
||||
for (File file : files) {
|
||||
Scanner s = null;
|
||||
String src = "";
|
||||
for (File file : files) {
|
||||
try {
|
||||
s = new Scanner(file).useDelimiter("\\A");
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
Log.d("iitcm", "failed to parse file " + file);
|
||||
}
|
||||
if (s != null)
|
||||
src = s.hasNext() ? s.next() : "";
|
||||
|
||||
// now we have all stuff together and can build the pref screen
|
||||
addPluginPreference(src, file.toString(), true);
|
||||
try {
|
||||
s = new Scanner(file).useDelimiter("\\A");
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
Log.d("iitcm", "failed to parse file " + file);
|
||||
}
|
||||
if (s != null)
|
||||
src = s.hasNext() ? s.next() : "";
|
||||
|
||||
// now we have all stuff together and can build the pref screen
|
||||
addPluginPreference(src, file.toString(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void addPluginPreference(String src, String plugin_key,
|
||||
boolean additional) {
|
||||
boolean user) {
|
||||
|
||||
// now parse plugin name, description and category
|
||||
String header = src.substring(src.indexOf("==UserScript=="),
|
||||
@ -137,9 +181,9 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity {
|
||||
plugin_name = plugin_name.replace("IITC Plugin: ", "");
|
||||
plugin_name = plugin_name.replace("IITC plugin: ", "");
|
||||
|
||||
// add [User] tag to additional plugins
|
||||
if (additional)
|
||||
plugin_cat = "[User] " + plugin_cat;
|
||||
// add [User] tag to user plugins
|
||||
if (user)
|
||||
plugin_cat = USER_PLUGIN + plugin_cat;
|
||||
|
||||
// now we have all stuff together and can build the preference
|
||||
// first check if we need a new category
|
||||
@ -160,12 +204,28 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity {
|
||||
}
|
||||
|
||||
void addHeaders() {
|
||||
boolean first_user = true;
|
||||
boolean first_official = true;
|
||||
// every fragment handles 1 plugin category
|
||||
// push the category to the fragment and add the header to the list
|
||||
for (Map.Entry<String, ArrayList<IITC_PluginPreference>> entry : sPlugins.entrySet()) {
|
||||
Bundle bundle = new Bundle();
|
||||
String plugin_cat = entry.getKey();
|
||||
bundle.putString("category", plugin_cat);
|
||||
if (plugin_cat.startsWith(USER_PLUGIN)) {
|
||||
if (first_user) {
|
||||
Header category = new Header();
|
||||
category.title = "User Plugins";
|
||||
first_user = false;
|
||||
mHeaders.add(category);
|
||||
}
|
||||
plugin_cat = plugin_cat.replace(USER_PLUGIN, "");
|
||||
} else if (first_official) {
|
||||
Header category = new Header();
|
||||
category.title = "Official Plugins";
|
||||
first_official = false;
|
||||
mHeaders.add(category);
|
||||
}
|
||||
Header newHeader = new Header();
|
||||
newHeader.title = plugin_cat;
|
||||
newHeader.fragmentArguments = bundle;
|
||||
@ -173,4 +233,118 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity {
|
||||
mHeaders.add(newHeader);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This code is only for header categories. Thx to Android that we haven't this by default and
|
||||
* thx to Stackoverflow for this post: http://stackoverflow.com/a/18720212
|
||||
*/
|
||||
private static class HeaderAdapter extends ArrayAdapter<Header> {
|
||||
static final int HEADER_TYPE_CATEGORY = 0;
|
||||
static final int HEADER_TYPE_NORMAL = 1;
|
||||
private static final int HEADER_TYPE_COUNT = HEADER_TYPE_NORMAL + 1;
|
||||
|
||||
private static class HeaderViewHolder {
|
||||
TextView title;
|
||||
TextView summary;
|
||||
}
|
||||
|
||||
private LayoutInflater mInflater;
|
||||
|
||||
static int getHeaderType(Header header) {
|
||||
if (header.fragment == null && header.intent == null) {
|
||||
return HEADER_TYPE_CATEGORY;
|
||||
} else {
|
||||
return HEADER_TYPE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
Header header = getItem(position);
|
||||
return getHeaderType(header);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areAllItemsEnabled() {
|
||||
return false; // because of categories
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int position) {
|
||||
return getItemViewType(position) != HEADER_TYPE_CATEGORY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
return HEADER_TYPE_COUNT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStableIds() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public HeaderAdapter(Context context, List<Header> objects) {
|
||||
super(context, 0, objects);
|
||||
|
||||
mInflater = (LayoutInflater) context
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
HeaderViewHolder holder;
|
||||
Header header = getItem(position);
|
||||
int headerType = getHeaderType(header);
|
||||
View view = null;
|
||||
|
||||
if (convertView == null) {
|
||||
holder = new HeaderViewHolder();
|
||||
switch (headerType) {
|
||||
case HEADER_TYPE_CATEGORY:
|
||||
view = new TextView(getContext(), null,
|
||||
android.R.attr.listSeparatorTextViewStyle);
|
||||
holder.title = (TextView) view;
|
||||
break;
|
||||
|
||||
case HEADER_TYPE_NORMAL:
|
||||
view = mInflater.inflate(R.layout.preference_header_item,
|
||||
parent, false);
|
||||
holder.title = (TextView) view
|
||||
.findViewById(R.id.plug_pref_title);
|
||||
holder.summary = (TextView) view
|
||||
.findViewById(R.id.plug_pref_summary);
|
||||
break;
|
||||
}
|
||||
view.setTag(holder);
|
||||
} else {
|
||||
view = convertView;
|
||||
holder = (HeaderViewHolder) view.getTag();
|
||||
}
|
||||
|
||||
// All view fields must be updated every time, because the view may
|
||||
// be recycled
|
||||
switch (headerType) {
|
||||
case HEADER_TYPE_CATEGORY:
|
||||
holder.title.setText(header.getTitle(getContext()
|
||||
.getResources()));
|
||||
break;
|
||||
case HEADER_TYPE_NORMAL:
|
||||
holder.title.setText(header.getTitle(getContext()
|
||||
.getResources()));
|
||||
CharSequence summary = header.getSummary(getContext()
|
||||
.getResources());
|
||||
if (!TextUtils.isEmpty(summary)) {
|
||||
holder.summary.setVisibility(View.VISIBLE);
|
||||
holder.summary.setText(summary);
|
||||
} else {
|
||||
holder.summary.setVisibility(View.GONE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -187,9 +187,9 @@ public class IITC_WebViewClient extends WebViewClient {
|
||||
+ plugin, false);
|
||||
else
|
||||
js += this.removePluginWrapper("plugins/" + plugin, true);
|
||||
// load additional iitc plugins
|
||||
// load user iitc plugins
|
||||
} else {
|
||||
Log.d("iitcm", "adding additional plugin " + plugin);
|
||||
Log.d("iitcm", "adding user plugin " + plugin);
|
||||
js += this.removePluginWrapper(plugin, false);
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ public class PluginsFragment extends PreferenceFragment {
|
||||
|
||||
// set action bar stuff
|
||||
ActionBar bar = getActivity().getActionBar();
|
||||
category = category.replace(IITC_PluginPreferenceActivity.USER_PLUGIN, "User ");
|
||||
bar.setTitle("IITC Plugins: " + category);
|
||||
bar.setDisplayHomeAsUpEnabled(true);
|
||||
getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
Reference in New Issue
Block a user