blob: 71c8a565e84d7c64727c882def4440beb35b1453 [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);
Pankaj Garg1c13cab2015-05-12 11:52:17 -0700172 mViewGroup.invalidate();
173 }
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
185 private void showCurrBitmap() {
186 if (mStationaryView.getVisibility() == View.VISIBLE) {
187 return;
188 }
189
190 Bitmap currBM = mModel.readSnapshot(mCurrIndex);
191 if (currBM != null) {
192 clampViewIfNeeded(mStationaryView);
193 mStationaryView.setImageBitmap(currBM);
194 goDormant();
195 mModel.deleteSnapshot(mCurrIndex);
196 }
197 }
198
199 private void clampViewIfNeeded(View view) {
200 int offset = 0;
201 if (mTitleBar.getY() >= 0) {
202 offset = mTitleBar.getNavigationBar().getMeasuredHeight();
203 }
204 view.setPadding(0, offset - view.getTop(), 0, 0);
205 }
206
207 public void onViewDragStateChanged(int state) {
208 if (ViewDragHelper.STATE_IDLE == state && !mbWaitForSettings) {
Pankaj Garg1c13cab2015-05-12 11:52:17 -0700209 goLive();
210 }
211 }
212
213 public void onViewReleased(View releasedChild, float xvel, float yvel) {
214 boolean bCrossedEventHorizon = Math.abs(mLeft) > mViewGroup.getWidth() / 2;
215
216 switch (mFromEdge) {
217 case ViewDragHelper.EDGE_LEFT:
218 if (xvel > 0 || (xvel == 0 && mLeft > 0 && bCrossedEventHorizon)) {
219 showCurrBitmap();
220 mbWaitForSettings = true;
221 mDragHelper.settleCapturedViewAt(
222 releasedChild.getMeasuredWidth(),
223 releasedChild.getTop());
224 break;
225 }
226 mDragHelper.settleCapturedViewAt(0, releasedChild.getTop());
227 break;
228 case ViewDragHelper.EDGE_RIGHT:
229 if (xvel < 0 || (xvel == 0 && mLeft < 0 && bCrossedEventHorizon)) {
230 showCurrBitmap();
231 mbWaitForSettings = true;
232 mDragHelper.settleCapturedViewAt(
233 -releasedChild.getMeasuredWidth(),
234 releasedChild.getTop());
235 break;
236 }
237 mDragHelper.settleCapturedViewAt(0, releasedChild.getTop());
238 break;
239 default:
240 mDragHelper.settleCapturedViewAt(0, releasedChild.getTop());
241 break;
242 }
243 mLeft = 0;
244 mViewGroup.invalidate();
245 }
246
247 public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
248 showCurrBitmap();
249 switch (mFromEdge) {
250 case ViewDragHelper.EDGE_LEFT:
251 mSlidingViewShadow.setX(left);
252 mViewGroup.invalidate();
253 break;
254 case ViewDragHelper.EDGE_RIGHT:
255 mSlidingViewShadow.setX(mViewGroup.getMeasuredWidth() + left
256 - mSlidingViewShadow.getMeasuredWidth());
257 mViewGroup.invalidate();
258 break;
259 default:
260 break;
261 }
262 }
263
264 public void onEdgeDragStarted(int edgeFlags, int pointerId) {
265 if (mFromEdge != ViewDragHelper.EDGE_TOP) {
266 return;
267 }
268
269 mCurrIndex = mActiveTab.getWebView().copyBackForwardList().getCurrentIndex();
270
271 mModel.updateSnapshot(mCurrIndex);
272
273 clampViewIfNeeded(mSettingsView);
274
275 if (ViewDragHelper.EDGE_LEFT == (edgeFlags & ViewDragHelper.EDGE_LEFT)) {
276 mFromEdge = ViewDragHelper.EDGE_LEFT;
277
278 mSettingsView.setTranslationX(-mViewGroup.getMeasuredWidth());
279 mSlidingViewShadow.setBackgroundResource(R.drawable.right_shade);
280 } else if (ViewDragHelper.EDGE_RIGHT == (edgeFlags & ViewDragHelper.EDGE_RIGHT)) {
281 mFromEdge = ViewDragHelper.EDGE_RIGHT;
282
283 mSettingsView.setTranslationX(mViewGroup.getMeasuredWidth());
284 mSlidingViewShadow.setBackgroundResource(R.drawable.left_shade);
285 }
286
287 mSettingsView.setVisibility(View.VISIBLE);
288 mSlidingViewShadow.setVisibility(View.VISIBLE);
289
290 showCurrBitmap();
291
292 mViewGroup.invalidate();
293 }
294
295 public int getOrderedChildIndex(int index) {
296 return mSlidingViewIndex;
297 }
298
299 public int getViewHorizontalDragRange(View child) {
300 return child.getMeasuredWidth();
301 }
302
303 public boolean tryCaptureView(View child, int pointerId) {
Pankaj Gargb2f6cce2015-07-16 15:13:49 -0700304 return (mFromEdge != ViewDragHelper.EDGE_TOP && child == mSettingsView);
Pankaj Garg1c13cab2015-05-12 11:52:17 -0700305 }
306
307 public int clampViewPositionHorizontal(View child, int left, int dx) {
308 mLeft = left;
309 return left;
310 }
311}
312