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