Apply IMMERSIVE mode to gallery (works only in Android 4.4)
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / QuickAction.java
1 /* ownCloud Android client application
2 * Copyright (C) 2011 Bartek Przybylski
3 * Copyright (C) 2012-2013 ownCloud Inc.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2,
7 * as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18 package com.owncloud.android.ui;
19
20 import android.content.Context;
21
22 import android.graphics.Rect;
23 import android.graphics.drawable.Drawable;
24
25 import android.widget.ImageView;
26 import android.widget.TextView;
27 import android.widget.LinearLayout;
28 import android.widget.ScrollView;
29
30 import android.view.Gravity;
31 import android.view.LayoutInflater;
32 import android.view.View;
33 import android.view.View.OnClickListener;
34 import android.view.ViewGroup.LayoutParams;
35 import android.view.ViewGroup;
36
37 import java.util.ArrayList;
38
39 import com.owncloud.android.R;
40
41
42 /**
43 * Popup window, shows action list as icon and text like the one in Gallery3D
44 * app.
45 *
46 * @author Lorensius. W. T
47 */
48 public class QuickAction extends CustomPopup {
49 private final View root;
50 private final ImageView mArrowUp;
51 private final ImageView mArrowDown;
52 private final LayoutInflater inflater;
53 private final Context context;
54
55 protected static final int ANIM_GROW_FROM_LEFT = 1;
56 protected static final int ANIM_GROW_FROM_RIGHT = 2;
57 protected static final int ANIM_GROW_FROM_CENTER = 3;
58 protected static final int ANIM_REFLECT = 4;
59 protected static final int ANIM_AUTO = 5;
60
61 private int animStyle;
62 private ViewGroup mTrack;
63 private ScrollView scroller;
64 private ArrayList<ActionItem> actionList;
65
66 /**
67 * Constructor
68 *
69 * @param anchor {@link View} on where the popup window should be displayed
70 */
71 public QuickAction(View anchor) {
72 super(anchor);
73
74 actionList = new ArrayList<ActionItem>();
75 context = anchor.getContext();
76 inflater = (LayoutInflater) context
77 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
78
79 root = (ViewGroup) inflater.inflate(R.layout.popup, null);
80
81 mArrowDown = (ImageView) root.findViewById(R.id.arrow_down);
82 mArrowUp = (ImageView) root.findViewById(R.id.arrow_up);
83
84 setContentView(root);
85
86 mTrack = (ViewGroup) root.findViewById(R.id.tracks);
87 scroller = (ScrollView) root.findViewById(R.id.scroller);
88 animStyle = ANIM_AUTO;
89 }
90
91 /**
92 * Set animation style
93 *
94 * @param animStyle animation style, default is set to ANIM_AUTO
95 */
96 public void setAnimStyle(int animStyle) {
97 this.animStyle = animStyle;
98 }
99
100 /**
101 * Add action item
102 *
103 * @param action {@link ActionItem} object
104 */
105 public void addActionItem(ActionItem action) {
106 actionList.add(action);
107 }
108
109 /**
110 * Show popup window. Popup is automatically positioned, on top or bottom of
111 * anchor view.
112 *
113 */
114 public void show() {
115 preShow();
116
117 int xPos, yPos;
118
119 int[] location = new int[2];
120
121 mAnchor.getLocationOnScreen(location);
122
123 Rect anchorRect = new Rect(location[0], location[1], location[0]
124 + mAnchor.getWidth(), location[1] + mAnchor.getHeight());
125
126 createActionList();
127
128 root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
129 LayoutParams.WRAP_CONTENT));
130 root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
131
132 int rootHeight = root.getMeasuredHeight();
133 int rootWidth = root.getMeasuredWidth();
134
135 int screenWidth = mWManager.getDefaultDisplay().getWidth();
136 int screenHeight = mWManager.getDefaultDisplay().getHeight();
137
138 // automatically get X coord of popup (top left)
139 if ((anchorRect.left + rootWidth) > screenWidth) {
140 xPos = anchorRect.left - (rootWidth - mAnchor.getWidth());
141 } else {
142 if (mAnchor.getWidth() > rootWidth) {
143 xPos = anchorRect.centerX() - (rootWidth / 2);
144 } else {
145 xPos = anchorRect.left;
146 }
147 }
148
149 int dyTop = anchorRect.top;
150 int dyBottom = screenHeight - anchorRect.bottom;
151
152 boolean onTop = (dyTop > dyBottom) ? true : false;
153
154 if (onTop) {
155 if (rootHeight > dyTop) {
156 yPos = 15;
157 LayoutParams l = scroller.getLayoutParams();
158 l.height = dyTop - mAnchor.getHeight();
159 } else {
160 yPos = anchorRect.top - rootHeight;
161 }
162 } else {
163 yPos = anchorRect.bottom;
164
165 if (rootHeight > dyBottom) {
166 LayoutParams l = scroller.getLayoutParams();
167 l.height = dyBottom;
168 }
169 }
170
171 showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up),
172 anchorRect.centerX() - xPos);
173
174 setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);
175
176 mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xPos, yPos);
177 }
178
179 /**
180 * Set animation style
181 *
182 * @param screenWidth screen width
183 * @param requestedX distance from left edge
184 * @param onTop flag to indicate where the popup should be displayed. Set
185 * TRUE if displayed on top of anchor view and vice versa
186 */
187 private void setAnimationStyle(int screenWidth, int requestedX,
188 boolean onTop) {
189 int arrowPos = requestedX - mArrowUp.getMeasuredWidth() / 2;
190
191 switch (animStyle) {
192 case ANIM_GROW_FROM_LEFT:
193 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left
194 : R.style.Animations_PopDownMenu_Left);
195 break;
196
197 case ANIM_GROW_FROM_RIGHT:
198 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right
199 : R.style.Animations_PopDownMenu_Right);
200 break;
201
202 case ANIM_GROW_FROM_CENTER:
203 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center
204 : R.style.Animations_PopDownMenu_Center);
205 break;
206
207 case ANIM_REFLECT:
208 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Reflect
209 : R.style.Animations_PopDownMenu_Reflect);
210 break;
211
212 case ANIM_AUTO:
213 if (arrowPos <= screenWidth / 4) {
214 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left
215 : R.style.Animations_PopDownMenu_Left);
216 } else if (arrowPos > screenWidth / 4
217 && arrowPos < 3 * (screenWidth / 4)) {
218 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center
219 : R.style.Animations_PopDownMenu_Center);
220 } else {
221 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right
222 : R.style.Animations_PopDownMenu_Right);
223 }
224
225 break;
226 }
227 }
228
229 /**
230 * Create action list
231 */
232 private void createActionList() {
233 View view;
234 String title;
235 Drawable icon;
236 OnClickListener listener;
237
238 for (int i = 0; i < actionList.size(); i++) {
239 title = actionList.get(i).getTitle();
240 icon = actionList.get(i).getIcon();
241 listener = actionList.get(i).getOnClickListerner();
242
243 view = getActionItem(title, icon, listener);
244
245 view.setFocusable(true);
246 view.setClickable(true);
247
248 mTrack.addView(view);
249 }
250 }
251
252 /**
253 * Get action item {@link View}
254 *
255 * @param title action item title
256 * @param icon {@link Drawable} action item icon
257 * @param listener {@link View.OnClickListener} action item listener
258 * @return action item {@link View}
259 */
260 private View getActionItem(String title, Drawable icon,
261 OnClickListener listener) {
262 LinearLayout container = (LinearLayout) inflater.inflate(
263 R.layout.action_item, null);
264
265 ImageView img = (ImageView) container.findViewById(R.id.icon);
266 TextView text = (TextView) container.findViewById(R.id.title);
267
268 if (icon != null) {
269 img.setImageDrawable(icon);
270 }
271
272 if (title != null) {
273 text.setText(title);
274 }
275
276 if (listener != null) {
277 container.setOnClickListener(listener);
278 }
279
280 return container;
281 }
282
283 /**
284 * Show arrow
285 *
286 * @param whichArrow arrow type resource id
287 * @param requestedX distance from left screen
288 */
289 private void showArrow(int whichArrow, int requestedX) {
290 final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp
291 : mArrowDown;
292 final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown
293 : mArrowUp;
294
295 final int arrowWidth = mArrowUp.getMeasuredWidth();
296
297 showArrow.setVisibility(View.VISIBLE);
298
299 ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams) showArrow
300 .getLayoutParams();
301
302 param.leftMargin = requestedX - arrowWidth / 2;
303
304 hideArrow.setVisibility(View.INVISIBLE);
305 }
306 }