Merge "Gallery: fix white screen after rapid scrolling"
diff --git a/res/layout/filtershow_editor_crop_landscape.xml b/res/layout/filtershow_editor_crop_landscape.xml
new file mode 100644
index 0000000..414a024
--- /dev/null
+++ b/res/layout/filtershow_editor_crop_landscape.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are
+  met:
+      * Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+      * Redistributions in binary form must reproduce the above
+        copyright notice, this list of conditions and the following
+        disclaimer in the documentation and/or other materials provided
+        with the distribution.
+      * Neither the name of The Linux Foundation nor the names of its
+        contributors may be used to endorse or promote products derived
+        from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+  ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/crop_panel_height_lanscape">
+
+    <FrameLayout
+        android:id="@+id/bottom_panel"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/crop_panel_height_lanscape"
+        android:background="@color/edit_actionbar_background"
+        android:layout_gravity="center_vertical">
+
+        <ImageButton
+            android:id="@+id/cancel"
+            android:layout_width="@dimen/category_actionbar_panel_height"
+            android:layout_height="@dimen/category_actionbar_panel_height"
+            android:background="@color/edit_actionbar_background"
+            android:layout_gravity="left|center_vertical"
+            android:src="@drawable/cancel" />
+
+
+        <ImageButton
+            android:id="@+id/done"
+            android:layout_width="@dimen/category_actionbar_panel_height"
+            android:layout_height="@dimen/category_actionbar_panel_height"
+            android:background="@color/edit_actionbar_background"
+            android:layout_gravity="right|center_vertical"
+            android:src="@drawable/done" />
+    </FrameLayout>
+
+    <LinearLayout
+        android:layout_width="360dp"
+        android:layout_height="@dimen/crop_panel_height_lanscape"
+        android:background="@android:color/transparent"
+        android:layout_gravity="center"
+        android:clickable="true"
+        android:orientation="horizontal">
+
+        <LinearLayout
+            android:id="@+id/leftPanel"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:layout_gravity="center_vertical"
+            android:background="@android:color/transparent"
+            android:orientation="vertical" >
+
+            <ImageButton
+                android:id="@+id/leftButton"
+                android:layout_width="match_parent"
+                android:layout_height="@dimen/crop_icon_size_landscape"
+                android:scaleType="centerInside"
+                android:background="@android:color/transparent" />
+
+            <TextView
+                android:id="@+id/leftText"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:clickable="true"
+                android:background="@android:color/transparent"
+                android:layout_marginTop="@dimen/crop_text_margin_padding"
+                android:textColor="#ffffff"
+                android:textSize="12sp" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/centerPanel"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:clickable="true"
+            android:layout_gravity="center_vertical"
+            android:background="@android:color/transparent"
+            android:orientation="vertical">
+
+            <ImageButton
+                android:id="@+id/centerButton"
+                android:layout_width="match_parent"
+                android:layout_height="@dimen/crop_icon_size_landscape"
+                android:scaleType="centerInside"
+                android:background="@android:color/transparent" />
+
+            <TextView
+                android:id="@+id/centerText"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:clickable="true"
+                android:background="@android:color/transparent"
+                android:layout_marginTop="@dimen/crop_text_margin_padding"
+                android:textColor="#ffffff"
+                android:textSize="12sp" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/rightPanel"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:clickable="true"
+            android:layout_gravity="center_vertical"
+            android:background="@android:color/transparent"
+            android:orientation="vertical">
+
+            <ImageButton
+                android:id="@+id/rightButton"
+                android:layout_width="match_parent"
+                android:layout_height="@dimen/crop_icon_size_landscape"
+                android:scaleType="centerInside"
+                android:background="@android:color/transparent" />
+
+            <TextView
+                android:id="@+id/rightText"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:clickable="true"
+                android:background="@android:color/transparent"
+                android:layout_marginTop="@dimen/crop_text_margin_padding"
+                android:textColor="#ffffff"
+                android:textSize="12sp" />
+        </LinearLayout>
+    </LinearLayout>
+
+
+</FrameLayout>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index aa7da66..e021d35 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -188,6 +188,8 @@
     <dimen name="slot_width_album">116dp</dimen>
     <dimen name="slot_height_album">116dp</dimen>
     <dimen name="crop_icon_size">30dp</dimen>
+    <dimen name="crop_icon_size_landscape">24dp</dimen>
+    <dimen name="crop_panel_height_lanscape">60dp</dimen>
     <dimen name="crop_icon_margin_padding">20dp</dimen>
     <dimen name="crop_text_margin_padding">6dp</dimen>
     <dimen name="crop_rect_stroke">2dp</dimen>
diff --git a/src/com/android/gallery3d/filtershow/FilterShowActivity.java b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
index f0af615..0f0604a 100644
--- a/src/com/android/gallery3d/filtershow/FilterShowActivity.java
+++ b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
@@ -92,7 +92,6 @@
 import com.android.gallery3d.filtershow.category.SwipableView;
 import com.android.gallery3d.filtershow.category.TrueScannerPanel;
 import com.android.gallery3d.filtershow.data.UserPresetsManager;
-import com.android.gallery3d.filtershow.editors.BasicEditor;
 import com.android.gallery3d.filtershow.editors.Editor;
 import com.android.gallery3d.filtershow.editors.EditorCrop;
 import com.android.gallery3d.filtershow.editors.EditorDualCamFusion;
@@ -214,7 +213,9 @@
     private ImageButton imgComparison;
     private String mPopUpText, mCancel;
     RelativeLayout rlImageContainer;
+    private int mEditrCropButtonSelect = 0;
     private boolean isComingFromEditorScreen;
+    private boolean mIsReloadByConfigurationChanged;
     private AlertDialog.Builder mBackAlertDialogBuilder;
 
     private ProgressDialog mLoadingDialog;
@@ -376,19 +377,7 @@
         }
         final int currentId = currentEditor.getID();
         if (currentId == EditorCrop.ID) {
-            new Runnable() {
-                @Override
-                public void run() {
-                    EditorCropPanel panel = new EditorCropPanel();
-                    FragmentTransaction transaction =
-                            getSupportFragmentManager().beginTransaction();
-                    transaction.remove(getSupportFragmentManager().findFragmentByTag(
-                            MainPanel.FRAGMENT_TAG));
-                    transaction.replace(R.id.main_panel_container, panel,
-                            MainPanel.FRAGMENT_TAG);
-                    transaction.commit();
-                }
-            }.run();
+            loadEditorCropPanel();
             return;
         }
         if (useStraightenPanel(currentId)) {
@@ -464,6 +453,22 @@
         return (EditorID == EditorStraighten.ID || EditorID == HazeBusterEditor.ID || EditorID == SeeStraightEditor.ID);
     }
 
+    private void loadEditorCropPanel() {
+        new Runnable() {
+            @Override
+            public void run() {
+                EditorCropPanel panel = new EditorCropPanel();
+                FragmentTransaction transaction =
+                        getSupportFragmentManager().beginTransaction();
+                transaction.remove(getSupportFragmentManager().findFragmentByTag(
+                        MainPanel.FRAGMENT_TAG));
+                transaction.replace(R.id.main_panel_container, panel,
+                        MainPanel.FRAGMENT_TAG);
+                transaction.commit();
+            }
+        }.run();
+    }
+
     public void leaveSeekBarPanel() {
         removeSeekBarPanel();
         showDefaultImageView();
@@ -1729,6 +1734,10 @@
         super.onConfigurationChanged(newConfig);
 
         setDefaultValues();
+        if (isShowEditCropPanel()) {
+            mIsReloadByConfigurationChanged = true;
+            loadEditorCropPanel();
+        }
         if (mMasterImage == null) {
             return;
         }
@@ -1769,6 +1778,9 @@
     }
 
     void resetHistory() {
+        if (mMasterImage == null) {
+            return;
+        }
         HistoryManager adapter = mMasterImage.getHistory();
         adapter.reset();
         HistoryItem historyItem = adapter.getItem(0);
@@ -1806,6 +1818,7 @@
         if (currentPanel instanceof MainPanel) {
             return;
         }
+        mIsReloadByConfigurationChanged = false;
         loadMainPanel();
         showDefaultImageView();
         showComparisonButton();
@@ -2018,4 +2031,29 @@
     public void setScaleImage(boolean isScaled) {
         mImageShow.scaleImage(isScaled, getBaseContext());
     }
+
+    public void saveEditorCropState(int select) {
+        mEditrCropButtonSelect = select;
+    }
+
+    public boolean isReloadByConfigurationChanged() {
+        return mIsReloadByConfigurationChanged;
+    }
+
+    public boolean isShowEditCropPanel() {
+        if (mCurrentEditor == null) {
+            return false;
+        }
+        Fragment currentPanel = getSupportFragmentManager().findFragmentByTag(
+                MainPanel.FRAGMENT_TAG);
+        if (currentPanel instanceof MainPanel) {
+            return false;
+        }
+        return mCurrentEditor.getID() == EditorCrop.ID;
+    }
+
+    public int getEditorCropButtonSelect() {
+        return mEditrCropButtonSelect;
+    }
+
 }
diff --git a/src/com/android/gallery3d/filtershow/category/BasicGeometryPanel.java b/src/com/android/gallery3d/filtershow/category/BasicGeometryPanel.java
index 52d16a5..466ecd8 100644
--- a/src/com/android/gallery3d/filtershow/category/BasicGeometryPanel.java
+++ b/src/com/android/gallery3d/filtershow/category/BasicGeometryPanel.java
@@ -30,6 +30,7 @@
 package com.android.gallery3d.filtershow.category;
 
 
+import android.content.res.Configuration;
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
 import android.view.LayoutInflater;
@@ -38,6 +39,7 @@
 import android.widget.ImageButton;
 import android.widget.TextView;
 
+import com.android.gallery3d.filtershow.FilterShowActivity;
 import org.codeaurora.gallery.R;
 
 public class BasicGeometryPanel extends Fragment {
@@ -54,8 +56,15 @@
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
                              Bundle savedInstanceState) {
-        mMainView = inflater.inflate(R.layout.filtershow_category_geometry_panel, container, false);
-        mEditorName = (TextView) mMainView.findViewById(R.id.editor_name);
+        FilterShowActivity activity = (FilterShowActivity) getActivity();
+        if (isLandscape() && activity.isShowEditCropPanel()) {
+            mMainView = inflater.inflate(R.layout.filtershow_editor_crop_landscape,
+                    container, false);
+        } else {
+            mMainView = inflater.inflate(R.layout.filtershow_category_geometry_panel,
+                    container, false);
+            mEditorName = (TextView) mMainView.findViewById(R.id.editor_name);
+        }
 
         initButtons();
         initTexts();
@@ -91,4 +100,10 @@
                 mMainView.findViewById(R.id.rightPanel)
         };
     }
+
+    protected boolean isLandscape() {
+        Configuration mConfiguration = this.getResources().getConfiguration();
+        return mConfiguration.orientation == Configuration.ORIENTATION_LANDSCAPE ?
+                true : false;
+    }
 }
diff --git a/src/com/android/gallery3d/filtershow/category/EditorCropPanel.java b/src/com/android/gallery3d/filtershow/category/EditorCropPanel.java
index 3e6124c..db7dfd0 100644
--- a/src/com/android/gallery3d/filtershow/category/EditorCropPanel.java
+++ b/src/com/android/gallery3d/filtershow/category/EditorCropPanel.java
@@ -30,6 +30,7 @@
 package com.android.gallery3d.filtershow.category;
 
 import android.app.Activity;
+import android.content.res.Configuration;
 import android.graphics.Color;
 import android.os.Bundle;
 import android.support.annotation.Nullable;
@@ -76,13 +77,19 @@
     public void onAttach(Activity activity) {
         super.onAttach(activity);
         FilterShowActivity filterShowActivity = (FilterShowActivity) activity;
+        if (filterShowActivity.isReloadByConfigurationChanged()) {
+            mSelectPosition = filterShowActivity.getEditorCropButtonSelect();
+        }
         mEditorCrop = (EditorCrop) filterShowActivity.getEditor(EditorCrop.ID);
     }
 
     @Override
     public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
-        mEditorName.setText(R.string.crop);
+        if (!isLandscape()) {
+            mEditorName.setText(R.string.crop);
+            mBottomPanel.setVisibility(View.VISIBLE);
+        }
         mMainView.setBackgroundColor(getContext().getResources().getColor(
                 R.color.edit_actionbar_background));
 
@@ -166,4 +173,11 @@
         }
         super.onDetach();
     }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        FilterShowActivity activity = (FilterShowActivity) getActivity();
+        activity.saveEditorCropState(mSelectPosition);
+    }
 }
diff --git a/src/com/android/gallery3d/filtershow/crop/CropDrawingUtils.java b/src/com/android/gallery3d/filtershow/crop/CropDrawingUtils.java
index b3f1af7..5937c78 100644
--- a/src/com/android/gallery3d/filtershow/crop/CropDrawingUtils.java
+++ b/src/com/android/gallery3d/filtershow/crop/CropDrawingUtils.java
@@ -75,7 +75,8 @@
         float x = 0;
         float y = 0;
         for (int i = 0; i < 2; i++) {
-            y = i * rectHeight + bounds.top + strokeWidth / 2;
+            y = i * rectHeight + bounds.top;
+
             canvas.drawLine(bounds.left - strokeWidth / 2, y, cornerLength + bounds.left, y, p);
             canvas.drawLine(bounds.right - cornerLength, y, bounds.right + strokeWidth / 2, y, p);
         }
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java b/src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java
index 294fbb7..4921c7c 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java
@@ -28,13 +28,14 @@
 import android.util.Log;
 import android.view.MotionEvent;
 
-import org.codeaurora.gallery.R;
+import com.android.gallery3d.filtershow.FilterShowActivity;
 import com.android.gallery3d.filtershow.crop.CropDrawingUtils;
 import com.android.gallery3d.filtershow.crop.CropMath;
 import com.android.gallery3d.filtershow.crop.CropObject;
 import com.android.gallery3d.filtershow.editors.EditorCrop;
 import com.android.gallery3d.filtershow.filters.FilterCropRepresentation;
 import com.android.gallery3d.filtershow.imageshow.GeometryMathUtils.GeometryHolder;
+import org.codeaurora.gallery.R;
 
 public class ImageCrop extends ImageShow {
     private static final String TAG = ImageCrop.class.getSimpleName();
@@ -232,9 +233,11 @@
     private void forceStateConsistency() {
         MasterImage master = MasterImage.getImage();
         Bitmap image = master.getFiltersOnlyImage();
+        FilterShowActivity filterShowActivity = (FilterShowActivity) getContext();
+        boolean isReload = filterShowActivity.isReloadByConfigurationChanged();
         int width = image.getWidth();
         int height = image.getHeight();
-        if (mCropObj == null || !mUpdateHolder.equals(mGeometry)
+        if (mCropObj == null || (!mUpdateHolder.equals(mGeometry) && !isReload)
                 || mImageBounds.width() != width || mImageBounds.height() != height
                 || !mLocalRep.getCrop().equals(mUpdateHolder.crop)) {
             mImageBounds.set(0, 0, width, height);
@@ -251,7 +254,12 @@
     @Override
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
         super.onSizeChanged(w, h, oldw, oldh);
-        clearDisplay();
+        FilterShowActivity filterShowActivity = (FilterShowActivity) getContext();
+        if (filterShowActivity.isShowEditCropPanel()) {
+            updateMatrix(w, h);
+        } else {
+            clearDisplay();
+        }
     }
 
     @Override
@@ -270,8 +278,13 @@
         if (mDisplayCropMatrix == null || mDisplayMatrix == null || mDisplayMatrixInverse == null) {
             mCropObj.unsetAspectRatio();
             Resources res = getContext().getResources();
-            int panelHeight = res.getDimensionPixelOffset(R.dimen.category_panel_height) +
-                    res.getDimensionPixelOffset(R.dimen.category_actionbar_panel_height);
+            int panelHeight = 0;
+            if (canvas.getWidth() < canvas.getHeight()) {
+                panelHeight = res.getDimensionPixelOffset(R.dimen.category_panel_height) +
+                        res.getDimensionPixelOffset(R.dimen.category_actionbar_panel_height);
+            } else {
+                panelHeight = res.getDimensionPixelOffset(R.dimen.crop_panel_height_lanscape);
+            }
             mDisplayMatrix = GeometryMathUtils.getFullGeometryToScreenMatrix(mGeometry,
                     bitmap.getWidth(), bitmap.getHeight(), canvas.getWidth(),
                     canvas.getHeight() - panelHeight);
@@ -331,4 +344,32 @@
     public void setEditor(EditorCrop editorCrop) {
         mEditorCrop = editorCrop;
     }
+
+    private void updateMatrix(int w, int h) {
+        Bitmap bitmap = MasterImage.getImage().getFiltersOnlyImage();
+        if (bitmap == null) {
+            MasterImage.getImage().invalidateFiltersOnly();
+        }
+        if (!mValidDraw || bitmap == null) {
+            return;
+        }
+        Resources res = getContext().getResources();
+        int panelHeight = 0;
+        if (w < h) {
+            panelHeight = res.getDimensionPixelOffset(R.dimen.category_panel_height) +
+                    res.getDimensionPixelOffset(R.dimen.category_actionbar_panel_height);
+        } else {
+            panelHeight = res.getDimensionPixelOffset(R.dimen.crop_panel_height_lanscape);
+        }
+        mDisplayMatrix = GeometryMathUtils.getFullGeometryToScreenMatrix(mGeometry,
+                bitmap.getWidth(), bitmap.getHeight(), w, h - panelHeight);
+        mDisplayCropMatrix = GeometryMathUtils.getFullGeometryToScreenMatrix(mGeometry,
+                bitmap.getWidth(), bitmap.getHeight(), w, h - panelHeight);
+        mDisplayMatrixInverse = new Matrix();
+        mDisplayMatrixInverse.reset();
+        if (!mDisplayCropMatrix.invert(mDisplayMatrixInverse)) {
+            Log.w(TAG, "could not invert display matrix");
+            mDisplayMatrixInverse = null;
+        }
+    }
 }