diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index ce51a727de..aadb9dabcd 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -19,6 +19,7 @@ </intent-filter> </activity> <activity android:label="@string/app_name" android:name="rombrowser" /> + <activity android:label="@string/app_name" android:name="com.retroarch.fileio.FileChooser" /> </application> <!-- Tell the system this app requires OpenGL ES 2.0. --> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> diff --git a/android/bin/classes/com/retroarch/R$drawable.class b/android/bin/classes/com/retroarch/R$drawable.class index 7978de43c0..d81ef13eca 100644 Binary files a/android/bin/classes/com/retroarch/R$drawable.class and b/android/bin/classes/com/retroarch/R$drawable.class differ diff --git a/android/bin/classes/com/retroarch/R$layout.class b/android/bin/classes/com/retroarch/R$layout.class index 481d24b928..ccc0670f71 100644 Binary files a/android/bin/classes/com/retroarch/R$layout.class and b/android/bin/classes/com/retroarch/R$layout.class differ diff --git a/android/bin/classes/com/retroarch/R$string.class b/android/bin/classes/com/retroarch/R$string.class index a6f1f30f88..e7e7cc3319 100644 Binary files a/android/bin/classes/com/retroarch/R$string.class and b/android/bin/classes/com/retroarch/R$string.class differ diff --git a/android/gen/com/retroarch/R.java b/android/gen/com/retroarch/R.java index c135920b23..e16daa4f61 100644 --- a/android/gen/com/retroarch/R.java +++ b/android/gen/com/retroarch/R.java @@ -11,27 +11,36 @@ public final class R { public static final class attr { } public static final class drawable { - public static final int ic_action_close=0x7f020000; - public static final int ic_action_history=0x7f020001; - public static final int ic_action_load=0x7f020002; - public static final int ic_action_main=0x7f020003; - public static final int ic_action_open=0x7f020004; - public static final int ic_action_save=0x7f020005; - public static final int ic_action_settings=0x7f020006; - public static final int ic_launcher=0x7f020007; + public static final int directory_icon=0x7f020000; + public static final int directory_up=0x7f020001; + public static final int file_icon=0x7f020002; + public static final int ic_action_close=0x7f020003; + public static final int ic_action_history=0x7f020004; + public static final int ic_action_load=0x7f020005; + public static final int ic_action_main=0x7f020006; + public static final int ic_action_open=0x7f020007; + public static final int ic_action_save=0x7f020008; + public static final int ic_action_settings=0x7f020009; + public static final int ic_launcher=0x7f02000a; } public static final class id { - public static final int close=0x7f060002; - public static final int history=0x7f060005; - public static final int load=0x7f060003; - public static final int main=0x7f060000; - public static final int open=0x7f060001; - public static final int save=0x7f060004; - public static final int settings=0x7f060006; + public static final int TextView01=0x7f060002; + public static final int TextView02=0x7f060003; + public static final int close=0x7f060006; + public static final int fileChooserSubmit=0x7f060000; + public static final int fileChooserView=0x7f060001; + public static final int history=0x7f060009; + public static final int load=0x7f060007; + public static final int main=0x7f060004; + public static final int open=0x7f060005; + public static final int save=0x7f060008; + public static final int settings=0x7f06000a; } public static final class layout { - public static final int main=0x7f030000; - public static final int rombrowser=0x7f030001; + public static final int file_choose=0x7f030000; + public static final int file_view=0x7f030001; + public static final int main=0x7f030002; + public static final int rombrowser=0x7f030003; } public static final class menu { public static final int main_menu=0x7f050000; diff --git a/android/src/com/retroarch/fileio/FileArrayAdapter.java b/android/src/com/retroarch/fileio/FileArrayAdapter.java new file mode 100644 index 0000000000..fed7983c7f --- /dev/null +++ b/android/src/com/retroarch/fileio/FileArrayAdapter.java @@ -0,0 +1,118 @@ +package com.retroarch.fileio; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Set; + +import com.retroarch.R; +import com.retroarch.R.layout; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.SectionIndexer; +import android.widget.TextView; + +public class FileArrayAdapter extends ArrayAdapter<Option> implements SectionIndexer +{ + HashMap<String, Integer> alphaIndexer; + String[] sections; + + private Context c; + private int id; + private List<Option>items; + + public FileArrayAdapter(Context context, int textViewResourceId, + List<Option> objects) { + super(context, textViewResourceId, objects); + c = context; + id = textViewResourceId; + items = objects; + + initAlphaIndexer(); + } + + private void initAlphaIndexer() + { + alphaIndexer = new HashMap<String, Integer>(); + int size = items.size(); + + for (int x = 0; x < size; x++) { + Option o = items.get(x); + + String ch = o.getName().substring(0, 1); + + ch = ch.toUpperCase(); + + if (!alphaIndexer.containsKey(ch)) + { + alphaIndexer.put(ch, x); + } + } + + Set<String> sectionLetters = alphaIndexer.keySet(); + + ArrayList<String> sectionList = new ArrayList<String>(sectionLetters); + + Collections.sort(sectionList); + + sections = new String[sectionList.size()]; + + sectionList.toArray(sections); + } + + public Option getItem(int i) + { + return items.get(i); + } + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View v = convertView; + if (v == null) { + LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + v = vi.inflate(id, null); + } + final Option o = items.get(position); + if (o != null) { + TextView t1 = (TextView) v.findViewById(R.id.TextView01); + TextView t2 = (TextView) v.findViewById(R.id.TextView02); + + if(t1!=null) + { + t1.setText(o.getName()); + } + if(t2!=null) + { + t2.setText(o.getData()); + } + + } + return v; + } + + public int getPositionForSection(int section) + { + // FIXME + if (section >= sections.length) + { + return 0; + } + return alphaIndexer.get(sections[section]); + } + + public int getSectionForPosition(int position) + { + return 1; + } + + public Object[] getSections() + { + return sections; + } + + +} diff --git a/android/src/com/retroarch/fileio/FileChooser.java b/android/src/com/retroarch/fileio/FileChooser.java new file mode 100644 index 0000000000..572e7d722a --- /dev/null +++ b/android/src/com/retroarch/fileio/FileChooser.java @@ -0,0 +1,264 @@ +package com.retroarch.fileio; + +import java.io.File; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Stack; + +import com.retroarch.R; +import com.retroarch.main; +import com.retroarch.R.layout; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.os.Environment; +import android.util.Log; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.Button; +import android.widget.ListView; +import android.widget.Toast; + +public class FileChooser extends Activity +{ + private static final String LOG_TAG = "FileChooser"; + + public static final String EXTRA_START_DIR = "StartDir"; + public static final String EXTRA_EXTENSIONS = "Extensions"; + public static final String EXTRA_TEMP_DIR = "TempDir"; + public static final String EXTRA_SELECT_DIR = "SelectDir"; + public static final String PAYLOAD_FILENAME = "Filename"; + public static final String PAYLOAD_SELECTED_DIR = "DirSelected"; + + private File currentDir; + private FileArrayAdapter adapter; + + private String _startDir; + private String _extensions; + private String _tempDir; + private String _selectDir; + + private Stack<String> _dirStack; + + private ListView _view; + + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + setContentView(R.layout.file_choose); + _view = (ListView)findViewById(R.id.fileChooserView); + + _startDir = getIntent().getStringExtra(EXTRA_START_DIR); + _extensions = getIntent().getStringExtra(EXTRA_EXTENSIONS); + _tempDir = getIntent().getStringExtra(EXTRA_TEMP_DIR); + _selectDir = getIntent().getStringExtra(EXTRA_SELECT_DIR); + + // clamp start dir and remove the / + if (_startDir == null) + { + _startDir = Environment.getExternalStorageDirectory().getAbsolutePath(); + } + else if (_startDir.endsWith("/")) + { + _startDir = _startDir.substring(0, _startDir.length() - 1); + } + + // push the start dir onto the stack + _dirStack = new Stack<String>(); + _dirStack.push(_startDir); + + // clamp extentions to all or extra specified + if (_extensions == null) + { + _extensions = ".*"; + } + + // clamp temp dir + if (_tempDir == null) + { + _tempDir = Environment.getExternalStorageDirectory().getAbsolutePath(); + } + + // regular filesystem dir + currentDir = new File(_startDir); + fill(currentDir); + + // are we dir selecting?, add button + if (_selectDir == null) + { + // hide button + Button b = (Button)findViewById(R.id.fileChooserSubmit); + b.setVisibility(Button.GONE); + } + else + { + // add on click submit + Button b = (Button)findViewById(R.id.fileChooserSubmit); + b.setOnClickListener(new OnClickListener() + { + + public void onClick(View v) + { + String s = _dirStack.peek(); + Toast.makeText(FileChooser.this, "Selected: " + s, Toast.LENGTH_SHORT).show(); + + Intent intent=new Intent(); + intent.putExtra(FileChooser.PAYLOAD_SELECTED_DIR, s); + setResult(RESULT_OK, intent); + + finish(); + } + }); + } + } + + public boolean onCreateOptionsMenu(Menu menu) + { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.main_menu, menu); + return true; + } + + public boolean onOptionsItemSelected(MenuItem item) + { + switch (item.getItemId()) + { + case R.id.main: + this.finish(); + break; + case R.id.open: + //TODO: Return to root dir + break; + default: + Toast.makeText(this, "MenuItem " + item.getTitle() + " selected.", Toast.LENGTH_SHORT).show(); + break; + } + + return true; + } + + + private void fill(File f) + { + File[]dirs = f.listFiles(); + this.setTitle("Current Dir: "+f.getAbsolutePath()); + List<Option>dir = new ArrayList<Option>(); + List<Option>fls = new ArrayList<Option>(); + try + { + for(File ff: dirs) + { + if(ff.isDirectory()) + { + dir.add(new Option(ff.getName() + "/","Folder",ff.getAbsolutePath())); + } + else + { + int dotIndex = ff.getName().lastIndexOf('.'); + if (dotIndex > 0) + { + String extension = ff.getName().substring(dotIndex+1).toLowerCase(); + if (extension.matches(_extensions)) + { + fls.add(new Option(ff.getName(),"File Size: "+ff.length(),ff.getAbsolutePath())); + } + } + } + } + } + catch(Exception e) + { + + } + + Collections.sort(dir); + Collections.sort(fls); + dir.addAll(fls); + + dir.add(0,new Option("..", "Parent Directory", f.getParent())); + + adapter = new FileArrayAdapter(FileChooser.this,R.layout.file_view,dir); + _view.setAdapter(adapter); + + _view.setOnItemClickListener(new OnItemClickListener() + { + + public void onItemClick(AdapterView<?> arg0, View arg1, + int arg2, long arg3) + { + int pos = arg0.getPositionForView(arg1); + Option o = adapter.getItem(pos); + if(o.getData().equalsIgnoreCase("folder")||o.getData().equalsIgnoreCase("parent directory")) + { + if (o.getPath() != null) + { + currentDir = new File(o.getPath()); + fill(currentDir); + _dirStack.push(o.getPath()); + } + } + else + { + String path = o.getPath(); + int dotIndex = path.lastIndexOf('.'); + String ext = null; + if (dotIndex >= 0) + { + ext = path.substring(dotIndex+1).toLowerCase(); + } + + onFileClick(o); + } + } + + }); + } + + + private void onFileClick(Option o) + { + Toast.makeText(this, "File Clicked: "+o.getName(), Toast.LENGTH_SHORT).show(); + + Intent intent=new Intent(); + intent.putExtra(FileChooser.PAYLOAD_FILENAME, o.getPath()); + setResult(RESULT_OK, intent); + + finish(); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) + { + if (_dirStack.size() > 1) + { + _dirStack.pop(); + File file = new File(_dirStack.peek()); + + currentDir = file; + fill(currentDir); + } + else + { + Intent intent = new Intent(); + setResult(RESULT_OK, intent); + + finish(); + } + + return true; + } + return super.onKeyDown(keyCode, event); + } + } diff --git a/android/src/com/retroarch/fileio/Option.java b/android/src/com/retroarch/fileio/Option.java new file mode 100644 index 0000000000..7b1bc201f9 --- /dev/null +++ b/android/src/com/retroarch/fileio/Option.java @@ -0,0 +1,34 @@ +package com.retroarch.fileio; + +public class Option implements Comparable<Option> +{ + private String name; + private String data; + private String path; + + public Option(String n,String d,String p) + { + name = n; + data = d; + path = p; + } + public String getName() + { + return name; + } + public String getData() + { + return data; + } + public String getPath() + { + return path; + } + + public int compareTo(Option o) { + if(this.name != null) + return this.name.toLowerCase().compareTo(o.getName().toLowerCase()); + else + throw new IllegalArgumentException(); + } +} diff --git a/android/src/com/retroarch/main.java b/android/src/com/retroarch/main.java index 05e6a629cb..fccffe9334 100644 --- a/android/src/com/retroarch/main.java +++ b/android/src/com/retroarch/main.java @@ -3,6 +3,7 @@ package com.retroarch; import com.retroarch.R; import com.retroarch.R.id; import com.retroarch.R.menu; +import com.retroarch.fileio.FileChooser; import android.app.Activity; import android.content.Intent; @@ -42,7 +43,7 @@ public class main extends Activity this.finish(); break; case R.id.open: - Intent myIntent = new Intent(main.this, rombrowser.class); + Intent myIntent = new Intent(main.this, FileChooser.class); main.this.startActivity(myIntent); break; default: diff --git a/android/src/com/retroarch/rombrowser.java b/android/src/com/retroarch/rombrowser.java deleted file mode 100644 index 0a794e43cc..0000000000 --- a/android/src/com/retroarch/rombrowser.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.retroarch; - -import com.retroarch.R.layout; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.widget.Toast; - -public class rombrowser extends Activity { - @Override - public void onCreate(Bundle savedInstanceState) - { - super.onCreate(savedInstanceState); - - setContentView(R.layout.rombrowser); - } - - public boolean onCreateOptionsMenu(Menu menu) - { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.main_menu, menu); - return true; - } - - public boolean onOptionsItemSelected(MenuItem item) - { - switch (item.getItemId()) - { - case R.id.main: - this.finish(); - break; - case R.id.open: - break; - default: - Toast.makeText(this, "MenuItem " + item.getTitle() + " selected.", Toast.LENGTH_SHORT).show(); - break; - } - - return true; - } -}