diff options
author | Iain Billett <iainbillett@gmail.com> | 2012-06-27 22:56:06 +0100 |
---|---|---|
committer | Iain Billett <iainbillett@gmail.com> | 2012-06-28 19:45:31 +0100 |
commit | 797df2912a91ad493f2368c508999d73635c8c35 (patch) | |
tree | 699e25e5a7832d51fff76b95416f4f9cca137bfd | |
parent | 677f10cdf0b6a7acb2f94fce8404b464061ccaf7 (diff) |
Some styling of document viewer. Transparent overlayed action bar with hide/show on tap. Navigation overlay with page thumbnails.
6 files changed, 302 insertions, 5 deletions
diff --git a/android/experimental/LibreOffice4Android/AndroidManifest.xml b/android/experimental/LibreOffice4Android/AndroidManifest.xml index fcf62103d2b1..9386d8c05edc 100644 --- a/android/experimental/LibreOffice4Android/AndroidManifest.xml +++ b/android/experimental/LibreOffice4Android/AndroidManifest.xml @@ -15,6 +15,7 @@ <!-- Original Document Loader activity - file Viewer --> <activity android:name=".android.DocumentLoader" + android:theme="@style/DocumentViewer" android:label="DocumentLoader" android:configChanges="orientation|keyboardHidden"> <!-- <intent-filter> diff --git a/android/experimental/LibreOffice4Android/res/layout/document_viewer.xml b/android/experimental/LibreOffice4Android/res/layout/document_viewer.xml new file mode 100644 index 000000000000..2f84be972d41 --- /dev/null +++ b/android/experimental/LibreOffice4Android/res/layout/document_viewer.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:id="@+id/document_viewer_root"> + <ViewFlipper + android:id="@+id/page_flipper" + android:layout_width="match_parent" + android:layout_height="match_parent" > + + </ViewFlipper> + <HorizontalScrollView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignBottom="@id/page_flipper" + android:background="#aa000000"> + <LinearLayout + android:id="@+id/navigator" + android:layout_width="wrap_content" + android:layout_height="150dp" + android:orientation="horizontal"> + </LinearLayout> + </HorizontalScrollView > + +</RelativeLayout>
\ No newline at end of file diff --git a/android/experimental/LibreOffice4Android/res/layout/navigation_grid_item.xml b/android/experimental/LibreOffice4Android/res/layout/navigation_grid_item.xml new file mode 100644 index 000000000000..75a27b3c70ac --- /dev/null +++ b/android/experimental/LibreOffice4Android/res/layout/navigation_grid_item.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="150dp" + android:layout_height="150dp" + android:layout_gravity="center" + android:background="#00880000" + android:orientation="vertical" > + <!-- Can I give all thumbs the same ID? works in grid adapter "getView" --> + <ImageView + android:src="@drawable/dummy_page" + android:id="@+id/thumbnail" + android:layout_width="120dp" + android:layout_height="120dp" + android:layout_margin="15dp" + android:layout_gravity="center"/> +</LinearLayout>
\ No newline at end of file diff --git a/android/experimental/LibreOffice4Android/res/values/styles.xml b/android/experimental/LibreOffice4Android/res/values/styles.xml index 5e74240f58c2..46edd6719438 100644 --- a/android/experimental/LibreOffice4Android/res/values/styles.xml +++ b/android/experimental/LibreOffice4Android/res/values/styles.xml @@ -6,7 +6,7 @@ <item name="android:actionBarStyle">@style/TransparentDarkActionBar</item> </style> <style name="TransparentDarkActionBar" parent="@android:style/Widget.Holo.ActionBar"> - <item name="android:background">#dd000000</item> + <item name="android:background">#bb000000</item> </style> </resources>
\ No newline at end of file diff --git a/android/experimental/LibreOffice4Android/src/org/libreoffice/android/DocumentLoader.java b/android/experimental/LibreOffice4Android/src/org/libreoffice/android/DocumentLoader.java index 9fa07f8661f6..2c839a5628ab 100644 --- a/android/experimental/LibreOffice4Android/src/org/libreoffice/android/DocumentLoader.java +++ b/android/experimental/LibreOffice4Android/src/org/libreoffice/android/DocumentLoader.java @@ -28,6 +28,7 @@ // "3" into a parameter below. package org.libreoffice.android; +import org.libreoffice.R; import android.app.Activity; import android.graphics.Bitmap; @@ -46,6 +47,23 @@ import android.widget.ImageView; import android.widget.TextView; import android.widget.ViewFlipper; import android.widget.ViewSwitcher; +import android.view.MenuItem; +import android.content.Intent; +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.BaseAdapter; +import android.view.View.OnClickListener; +// Obsolete? +import android.widget.AdapterView.OnItemClickListener; +import android.widget.GridView; +import android.widget.AdapterView; + +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.LinearLayout.LayoutParams; +import android.graphics.BitmapFactory; import com.polites.android.GestureImageView; @@ -71,6 +89,7 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import org.libreoffice.android.Bootstrap; +import org.libreoffice.ui.LibreOfficeUIActivity; public class DocumentLoader extends Activity @@ -102,6 +121,11 @@ public class DocumentLoader ViewGroup.LayoutParams matchParent; ViewFlipper flipper; + + Bundle extras; + + LinearLayout ll ; + LayoutInflater inflater ; class GestureListener extends GestureDetector.SimpleOnGestureListener @@ -153,6 +177,29 @@ public class DocumentLoader } return false; } + + @Override + public boolean onSingleTapUp(MotionEvent event){ + if( getActionBar().isShowing() ){ + getActionBar().hide(); + }else{ + getActionBar().show(); + } + return true; + } + + @Override + public boolean onDoubleTap(MotionEvent event){ + LinearLayout ll = (LinearLayout)findViewById( R.id.navigator); + if( ll.isShown() ){ + ll.setVisibility( View.GONE ); + }else{ + ll.setVisibility( View.VISIBLE ); + } + return true; + } + + } class MyXController @@ -303,6 +350,90 @@ public class DocumentLoader return null; } + + ByteBuffer renderPage(int number, int width , int height) + { + try { + // Use dummySmallDevice with no scale of offset just to find out + // the paper size of this page. + + PropertyValue renderProps[] = new PropertyValue[3]; + renderProps[0] = new PropertyValue(); + renderProps[0].Name = "IsPrinter"; + renderProps[0].Value = new Boolean(true); + renderProps[1] = new PropertyValue(); + renderProps[1].Name = "RenderDevice"; + renderProps[1].Value = dummySmallDevice; + renderProps[2] = new PropertyValue(); + renderProps[2].Name = "View"; + renderProps[2].Value = new MyXController(); + + // getRenderer returns a set of properties that include the PageSize + long t0 = System.currentTimeMillis(); + PropertyValue rendererProps[] = renderable.getRenderer(number, doc, renderProps); + long t1 = System.currentTimeMillis(); + Log.i(TAG, "w,h getRenderer took " + ((t1-t0)-timingOverhead) + " ms"); + + int pageWidth = 0, pageHeight = 0; + for (int i = 0; i < rendererProps.length; i++) { + if (rendererProps[i].Name.equals("PageSize")) { + pageWidth = ((Size) rendererProps[i].Value).Width; + pageHeight = ((Size) rendererProps[i].Value).Height; + Log.i(TAG, " w,h PageSize: " + pageWidth + "x" + pageHeight); + } + } + + // Create a new device with the correct scale and offset + ByteBuffer bb = ByteBuffer.allocateDirect(width*height*4); + long wrapped_bb = Bootstrap.new_byte_buffer_wrapper(bb); + + XDevice device; + if (pageWidth == 0) { + // Huh? + device = toolkit.createScreenCompatibleDeviceUsingBuffer(width, height, 1, 1, 0, 0, wrapped_bb); + } else { + + // Scale so that it fits our device which has a resolution of 96/in (see + // SvpSalGraphics::GetResolution()). The page size returned from getRenderer() is in 1/mm * 100. + + int scaleNumerator, scaleDenominator; + + // If the view has a wider aspect ratio than the page, fit + // height; otherwise, fit width + if ((double) width / height > (double) pageWidth / pageHeight) { + scaleNumerator = height; + scaleDenominator = pageHeight / 2540 * 96; + } else { + scaleNumerator = width; + scaleDenominator = pageWidth / 2540 * 96; + } + Log.i(TAG, "w,h Scaling with " + scaleNumerator + "/" + scaleDenominator); + + device = toolkit.createScreenCompatibleDeviceUsingBuffer(width, height, + scaleNumerator, scaleDenominator, + 0, 0, + wrapped_bb); + } + + // Update the property that points to the device + renderProps[1].Value = device; + + t0 = System.currentTimeMillis(); + renderable.render(number, doc, renderProps); + t1 = System.currentTimeMillis(); + Log.i(TAG, "w,h Rendering page " + number + " took " + ((t1-t0)-timingOverhead) + " ms"); + + Bootstrap.force_full_alpha_bb(bb, 0, width * height * 4); + + return bb; + } + catch (Exception e) { + e.printStackTrace(System.err); + finish(); + } + + return null; + } enum PageState { NONEXISTENT, LOADING, READY }; @@ -384,6 +515,79 @@ public class DocumentLoader } } + class ThumbnailView + extends ViewSwitcher + { + int currentPageNumber = -1; + TextView waitView; + View thumbnailView; + //PageState state = PageState.NONEXISTENT; + Bitmap bm; + + class ThumbLoadTask + extends AsyncTask<Integer, Void, Integer> + { + protected Integer doInBackground(Integer... params) + { + int number = params[0]; + + if (number >= pageCount) + return -1; + + //state = PageState.LOADING; + ByteBuffer bb = renderPage( number , 120 , 120); + bm = Bitmap.createBitmap( 120 , 120 , Bitmap.Config.ARGB_8888); + bm.copyPixelsFromBuffer(bb); + + return number; + } + + protected void onPostExecute(Integer result) + { + Log.i(TAG, "onPostExecute: " + result); + if (result == -1) + return; + + //ImageView imageView = new ImageView(DocumentLoader.this); + + ImageView thumbImage = new ImageView(DocumentLoader.this);//(ImageView)findViewById( R.id.thumbnail ); + thumbImage.setImageBitmap(bm); + + thumbImage.setScaleY(-1); + + Log.i( TAG, Integer.toString( thumbImage.getWidth() ) ); + if (getChildCount() == 1) + removeViewAt(0); + addView(thumbImage, matchParent); + showNext(); + //state = PageState.READY; + } + } + + void display(int number) + { + Log.i(TAG, "PageViewer display(" + number + ")"); + if (number >= 0) + waitView.setText("Page " + (number+1) + ", wait..."); + //state = PageState.NONEXISTENT; + + if (number >= 0) { + new ThumbLoadTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, number); + } + } + + ThumbnailView(int number) + { + super(DocumentLoader.this); + waitView = new TextView( DocumentLoader.this ); + thumbnailView = inflater.inflate( R.layout.navigation_grid_item , null); + + display(number); + + + } + } + class DocumentLoadTask extends AsyncTask<String, Void, Void> { @@ -510,6 +714,8 @@ public class DocumentLoader { super.onCreate(savedInstanceState); + extras = getIntent().getExtras(); + gestureDetector = new GestureDetector(this, new GestureListener()); try { @@ -568,8 +774,9 @@ public class DocumentLoader // Load the wanted document new DocumentLoadTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, "file://" + input); - flipper = new ViewFlipper(this); - + setContentView( R.layout.document_viewer ); + //flipper = new ViewFlipper(this); + flipper = (ViewFlipper)findViewById( R.id.page_flipper ); matchParent = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); flipper.addView(new PageViewer(0), 0, matchParent); @@ -577,8 +784,38 @@ public class DocumentLoader flipper.addView(new PageViewer(i+1), i+1, matchParent); for (int i = 0; i < PAGECACHE_PLUSMINUS; i++) flipper.addView(new PageViewer(-1), PAGECACHE_PLUSMINUS + i+1, matchParent); - - setContentView(flipper); + + ll = (LinearLayout)findViewById( R.id.navigator); + inflater = (LayoutInflater) getApplicationContext().getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + + + + //ThumbnailView pv = new ThumbnailView(0); + /*Bitmap thumbnailBitmap = Bitmap.createBitmap(120, 120, Bitmap.Config.ARGB_8888); + thumbnailBitmap.copyPixelsFromBuffer(bb); + ImageView pageImage = (ImageView)findViewById( R.id.thumbnail ); + pageImage.setImageBitmap( thumbnailBitmap ); + */ + + + for( int i = 0; i < 2 ; i++ ){ + View thumbnailView = inflater.inflate( R.layout.navigation_grid_item , null ); + ThumbnailView thumb = new ThumbnailView( i ); + final int pos = i; + thumb.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + // TODO Auto-generated method stub + Log.d("nav" , Integer.toString( pos ) ); + //(PageViewer)flipper.getChildAt( (flipper.getDisplayedChild() + PAGECACHE_PLUSMINUS) % PAGECACHE_SIZE)).display( ( (PageViewer)flipper.getCurrentView() ).currentPageNumber + PAGECACHE_PLUSMINUS); + } + }); + ll.addView ( thumb ); + } + + } catch (Exception e) { e.printStackTrace(System.err); @@ -591,6 +828,21 @@ public class DocumentLoader { return gestureDetector.onTouchEvent(event); } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + // app icon in action bar clicked; go home + Intent intent = new Intent(this, LibreOfficeUIActivity.class); + intent.putExtras( extras ); + //intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + return true; + default: + return super.onOptionsItemSelected(item); + } + } } // vim:set shiftwidth=4 softtabstop=4 expandtab: diff --git a/android/experimental/LibreOffice4Android/src/org/libreoffice/ui/LibreOfficeUIActivity.java b/android/experimental/LibreOffice4Android/src/org/libreoffice/ui/LibreOfficeUIActivity.java index 420b48588a8c..7721d2b8898a 100644 --- a/android/experimental/LibreOffice4Android/src/org/libreoffice/ui/LibreOfficeUIActivity.java +++ b/android/experimental/LibreOffice4Android/src/org/libreoffice/ui/LibreOfficeUIActivity.java @@ -169,6 +169,9 @@ public class LibreOfficeUIActivity extends Activity implements OnNavigationListe */ Intent i = new Intent( this , DocumentLoader.class ); i.putExtra("input",new File( currentDirectory , file).getAbsolutePath() ); + i.putExtra( CURRENT_DIRECTORY_KEY , currentDirectory.getAbsolutePath() ); + i.putExtra( FILTER_MODE_KEY , filterMode ); + i.putExtra( EXPLORER_VIEW_TYPE_KEY , viewMode ); startActivity( i ); } |