blob: 105434b4f3beb53c8297cc24ddf63ecfa882d3c1 [file] [log] [blame]
Pankaj Garg1c13cab2015-05-12 11:52:17 -07001/*
2 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30package com.android.browser;
31
32import android.graphics.Bitmap;
33import android.os.AsyncTask;
34import android.support.v4.widget.ViewDragHelper;
35import android.view.View;
36import android.view.ViewGroup;
37import android.widget.Button;
38import android.widget.ImageView;
39import android.widget.LinearLayout;
40import android.widget.RadioButton;
41import android.widget.RadioGroup;
42import android.widget.Toast;
43
44public class EdgeSwipeSettings extends ViewDragHelper.Callback {
45 private ViewDragHelper mDragHelper;
46 private int mFromEdge = ViewDragHelper.EDGE_TOP;
47 private int mLeft = 0;
48
49 private ImageView mSlidingViewShadow;
50 private LinearLayout mSettingsView;
51 private DraggableFrameLayout mViewGroup;
52 private View mLiveView;
53 private ImageView mStationaryView;
54
55 private int mSlidingViewIndex;
56 private int mCurrIndex;
57
58 private EdgeSwipeModel mModel;
59 private Tab mActiveTab;
60 private TitleBar mTitleBar;
61
62 private boolean mbWaitForSettings = false;
63
64 public EdgeSwipeSettings(final View container,
65 int stationaryViewId,
66 int settingViewId,
67 int slidingViewShadowId,
68 int liveViewId,
69 int viewGroupId,
70 final BaseUi ui) {
71 DraggableFrameLayout viewGroup = (DraggableFrameLayout)
72 container.findViewById(viewGroupId);
73
74 mSlidingViewShadow = (ImageView) container.findViewById(slidingViewShadowId);
75 mSettingsView = (LinearLayout) container.findViewById(settingViewId);
76 mStationaryView = (ImageView) container.findViewById(stationaryViewId);
77 mLiveView = container.findViewById(liveViewId);
78 mViewGroup = (DraggableFrameLayout) container.findViewById(viewGroupId);
79
80 final int childCount = mViewGroup.getChildCount();
81
82 for (int i = childCount - 1; i >= 0; i--) {
83 final View child = mViewGroup.getChildAt(i);
84 if (mSettingsView == child) {
85 mSlidingViewIndex = i;
86 break;
87 }
88 }
89
90 mActiveTab = ui.getActiveTab();
91 mTitleBar = ui.getTitleBar();
92 mModel = new EdgeSwipeModel(mActiveTab, mTitleBar);
93
94 mDragHelper = ViewDragHelper.create(viewGroup, 0.5f, this);
95 mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT | ViewDragHelper.EDGE_RIGHT);
96 mViewGroup.setDragHelper(mDragHelper);
97
98 final Button closeBtn =
99 (Button) container.findViewById(R.id.edge_sliding_settings_close_btn);
100 closeBtn.setOnClickListener(
101 new View.OnClickListener() {
102 public void onClick(View v) {
Pankaj Garg1c13cab2015-05-12 11:52:17 -0700103 goLive();
104 }
105 }
106 );
107
108 final RadioButton temporalNavButton =
109 (RadioButton) container.findViewById(R.id.edge_sliding_settings_options_temporal);
110 temporalNavButton.setOnClickListener(
111 new View.OnClickListener() {
112 public void onClick(View v) {
Pankaj Garg1c13cab2015-05-12 11:52:17 -0700113 BrowserSettings.getInstance().setEdgeSwipeTemporal();
114 goLive();
115 applySettingsAndRefresh(ui, container);
116 Toast toast = Toast.makeText(ui.getActivity().getApplicationContext(),
117 R.string.pref_temporal_edge_swipe_enabled_toast, Toast.LENGTH_SHORT);
118 toast.show();
119 }
120 }
121 );
122
123 final RadioButton spatialNavButton =
124 (RadioButton) container.findViewById(R.id.edge_sliding_settings_options_spatial);
125 spatialNavButton.setOnClickListener(
126 new View.OnClickListener() {
127 public void onClick(View v) {
Pankaj Garg1c13cab2015-05-12 11:52:17 -0700128 BrowserSettings.getInstance().setEdgeSwipeSpatial();
129 goLive();
130 applySettingsAndRefresh(ui, container);
131 Toast toast = Toast.makeText(ui.getActivity().getApplicationContext(),
132 R.string.pref_spatial_edge_swipe_enabled_toast, Toast.LENGTH_SHORT);
133 toast.show();
134 }
135 }
136 );
137
138 final RadioButton disabledNavButton =
139 (RadioButton) container.findViewById(R.id.edge_sliding_settings_options_disabled);
140 disabledNavButton.setOnClickListener(
141 new View.OnClickListener() {
142 public void onClick(View v) {
Pankaj Garg1c13cab2015-05-12 11:52:17 -0700143 BrowserSettings.getInstance().setEdgeSwipeDisabled();
144 goLive();
145 applySettingsAndRefresh(ui, container);
146 Toast toast = Toast.makeText(ui.getActivity().getApplicationContext(),
147 R.string.pref_edge_swipe_disabled_toast, Toast.LENGTH_SHORT);
148 toast.show();
149 }
150 }
151 );
152 }
153
154 private void applySettingsAndRefresh(final BaseUi ui, final View container) {
155 new AsyncTask<Void, Void, Void>() {
156 @Override
157 protected Void doInBackground(Void... unused) {
158 mDragHelper = null;
159 ui.refreshEdgeSwipeController(container);
160 return null;
161 }
162 }.execute();
163 }
164
165 private void goLive() {
Pankaj Gargb2f6cce2015-07-16 15:13:49 -0700166 mbWaitForSettings = false;
Pankaj Garg1c13cab2015-05-12 11:52:17 -0700167 mFromEdge = ViewDragHelper.EDGE_TOP;
168 mLiveView.setVisibility(View.VISIBLE);
169 mStationaryView.setVisibility(View.GONE);
170 mSlidingViewShadow.setVisibility(View.GONE);
Pankaj Gargb2f6cce2015-07-16 15:13:49 -0700171 mSettingsView.setVisibility(View.GONE);
Sagar Dhawancab418e2015-09-15 13:14:17 -0700172 mViewGroup.postInvalidate();
Pankaj Garg1c13cab2015-05-12 11:52:17 -0700173 }
174
175 private void goDormant() {
176 mLiveView.setVisibility(View.GONE);
177 mStationaryView.setVisibility(View.VISIBLE);
178 mViewGroup.invalidate();
179 }
180
181 public void onConfigurationChanged() {
Pankaj Garg1c13cab2015-05-12 11:52:17 -0700182 goLive();
183 }
184
Sagar Dhawan05e3c352015-09-07 15:24:33 +0200185 public void cleanup() {
186 synchronized (this) {
187 goLive();
188 mModel.cleanup();
189 }
190 }
191
192
Pankaj Garg1c13cab2015-05-12 11:52:17 -0700193 private void showCurrBitmap() {
194 if (mStationaryView.getVisibility() == View.VISIBLE) {
195 return;
196 }
197
198 Bitmap currBM = mModel.readSnapshot(mCurrIndex);
199 if (currBM != null) {
200 clampViewIfNeeded(mStationaryView);
201 mStationaryView.setImageBitmap(currBM);
202 goDormant();
203 mModel.deleteSnapshot(mCurrIndex);
204 }
205 }
206
207 private void clampViewIfNeeded(View view) {
208 int offset = 0;
209 if (mTitleBar.getY() >= 0) {
210 offset = mTitleBar.getNavigationBar().getMeasuredHeight();
211 }
212 view.setPadding(0, offset - view.getTop(), 0, 0);
213 }
214
215 public void onViewDragStateChanged(int state) {
216 if (ViewDragHelper.STATE_IDLE == state && !mbWaitForSettings) {
Pankaj Garg1c13cab2015-05-12 11:52:17 -0700217 goLive();
218 }
219 }
220
221 public void onViewReleased(View releasedChild, float xvel, float yvel) {
222 boolean bCrossedEventHorizon = Math.abs(mLeft) > mViewGroup.getWidth() / 2;
223
224 switch (mFromEdge) {
225 case ViewDragHelper.EDGE_LEFT:
226 if (xvel > 0 || (xvel == 0 && mLeft > 0 && bCrossedEventHorizon)) {
227 showCurrBitmap();
228 mbWaitForSettings = true;
229 mDragHelper.settleCapturedViewAt(
230 releasedChild.getMeasuredWidth(),
231 releasedChild.getTop());
232 break;
233 }
234 mDragHelper.settleCapturedViewAt(0, releasedChild.getTop());
235 break;
236 case ViewDragHelper.EDGE_RIGHT:
237 if (xvel < 0 || (xvel == 0 && mLeft < 0 && bCrossedEventHorizon)) {
238 showCurrBitmap();
239 mbWaitForSettings = true;
240 mDragHelper.settleCapturedViewAt(
241 -releasedChild.getMeasuredWidth(),
242 releasedChild.getTop());
243 break;
244 }
245 mDragHelper.settleCapturedViewAt(0, releasedChild.getTop());
246 break;
247 default:
248 mDragHelper.settleCapturedViewAt(0, releasedChild.getTop());
249 break;
250 }
251 mLeft = 0;
252 mViewGroup.invalidate();
253 }
254
255 public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
256 showCurrBitmap();
257 switch (mFromEdge) {
258 case ViewDragHelper.EDGE_LEFT:
259 mSlidingViewShadow.setX(left);
260 mViewGroup.invalidate();
261 break;
262 case ViewDragHelper.EDGE_RIGHT:
263 mSlidingViewShadow.setX(mViewGroup.getMeasuredWidth() + left
264 - mSlidingViewShadow.getMeasuredWidth());
265 mViewGroup.invalidate();
266 break;
267 default:
268 break;
269 }
270 }
271
272 public void onEdgeDragStarted(int edgeFlags, int pointerId) {
273 if (mFromEdge != ViewDragHelper.EDGE_TOP) {
274 return;
275 }
276
277 mCurrIndex = mActiveTab.getWebView().copyBackForwardList().getCurrentIndex();
278
279 mModel.updateSnapshot(mCurrIndex);
280
281 clampViewIfNeeded(mSettingsView);
282
283 if (ViewDragHelper.EDGE_LEFT == (edgeFlags & ViewDragHelper.EDGE_LEFT)) {
284 mFromEdge = ViewDragHelper.EDGE_LEFT;
285
286 mSettingsView.setTranslationX(-mViewGroup.getMeasuredWidth());
287 mSlidingViewShadow.setBackgroundResource(R.drawable.right_shade);
288 } else if (ViewDragHelper.EDGE_RIGHT == (edgeFlags & ViewDragHelper.EDGE_RIGHT)) {
289 mFromEdge = ViewDragHelper.EDGE_RIGHT;
290
291 mSettingsView.setTranslationX(mViewGroup.getMeasuredWidth());
292 mSlidingViewShadow.setBackgroundResource(R.drawable.left_shade);
293 }
294
295 mSettingsView.setVisibility(View.VISIBLE);
296 mSlidingViewShadow.setVisibility(View.VISIBLE);
297
298 showCurrBitmap();
299
300 mViewGroup.invalidate();
301 }
302
303 public int getOrderedChildIndex(int index) {
304 return mSlidingViewIndex;
305 }
306
307 public int getViewHorizontalDragRange(View child) {
308 return child.getMeasuredWidth();
309 }
310
311 public boolean tryCaptureView(View child, int pointerId) {
Pankaj Gargb2f6cce2015-07-16 15:13:49 -0700312 return (mFromEdge != ViewDragHelper.EDGE_TOP && child == mSettingsView);
Pankaj Garg1c13cab2015-05-12 11:52:17 -0700313 }
314
315 public int clampViewPositionHorizontal(View child, int left, int dx) {
316 mLeft = left;
317 return left;
318 }
319}