Copyright note fixes
[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 * Popup window, shows action list as icon and text like the one in Gallery3D
43 * app.
44 *
45 * @author Lorensius. W. T
46 */
47 public class QuickAction extends CustomPopup {
48 private final View root;
49 private final ImageView mArrowUp;
50 private final ImageView mArrowDown;
51 private final LayoutInflater inflater;
52 private final Context context;
53
54 protected static final int ANIM_GROW_FROM_LEFT = 1;
55 protected static final int ANIM_GROW_FROM_RIGHT = 2;
56 protected static final int ANIM_GROW_FROM_CENTER = 3;
57 protected static final int ANIM_REFLECT = 4;
58 protected static final int ANIM_AUTO = 5;
59
60 private int animStyle;
61 private ViewGroup mTrack;
62 private ScrollView scroller;
63 private ArrayList<ActionItem> actionList;
64
65 /**
66 * Constructor
67 *
68 * @param anchor {@link View} on where the popup window should be displayed
69 */
70 public QuickAction(View anchor) {
71 super(anchor);
72
73 actionList = new ArrayList<ActionItem>();
74 context = anchor.getContext();
75 inflater = (LayoutInflater) context
76 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
77
78 root = (ViewGroup) inflater.inflate(R.layout.popup, null);
79
80 mArrowDown = (ImageView) root.findViewById(R.id.arrow_down);
81 mArrowUp = (ImageView) root.findViewById(R.id.arrow_up);
82
83 setContentView(root);
84
85 mTrack = (ViewGroup) root.findViewById(R.id.tracks);
86 scroller = (ScrollView) root.findViewById(R.id.scroller);
87 animStyle = ANIM_AUTO;
88 }
89
90 /**
91 * Set animation style
92 *
93 * @param animStyle animation style, default is set to ANIM_AUTO
94 */
95 public void setAnimStyle(int animStyle) {
96 this.animStyle = animStyle;
97 }
98
99 /**
100 * Add action item
101 *
102 * @param action {@link ActionItem} object
103 */
104 public void addActionItem(ActionItem action) {
105 actionList.add(action);
106 }
107
108 /**
109 * Show popup window. Popup is automatically positioned, on top or bottom of
110 * anchor view.
111 *
112 */
113 public void show() {
114 preShow();
115
116 int xPos, yPos;
117
118 int[] location = new int[2];
119
120 mAnchor.getLocationOnScreen(location);
121
122 Rect anchorRect = new Rect(location[0], location[1], location[0]
123 + mAnchor.getWidth(), location[1] + mAnchor.getHeight());
124
125 createActionList();
126
127 root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
128 LayoutParams.WRAP_CONTENT));
129 root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
130
131 int rootHeight = root.getMeasuredHeight();
132 int rootWidth = root.getMeasuredWidth();
133
134 int screenWidth = mWManager.getDefaultDisplay().getWidth();
135 int screenHeight = mWManager.getDefaultDisplay().getHeight();
136
137 // automatically get X coord of popup (top left)
138 if ((anchorRect.left + rootWidth) > screenWidth) {
139 xPos = anchorRect.left - (rootWidth - mAnchor.getWidth());
140 } else {
141 if (mAnchor.getWidth() > rootWidth) {
142 xPos = anchorRect.centerX() - (rootWidth / 2);
143 } else {
144 xPos = anchorRect.left;
145 }
146 }
147
148 int dyTop = anchorRect.top;
149 int dyBottom = screenHeight - anchorRect.bottom;
150
151 boolean onTop = (dyTop > dyBottom) ? true : false;
152
153 if (onTop) {
154 if (rootHeight > dyTop) {
155 yPos = 15;
156 LayoutParams l = scroller.getLayoutParams();
157 l.height = dyTop - mAnchor.getHeight();
158 } else {
159 yPos = anchorRect.top - rootHeight;
160 }
161 } else {
162 yPos = anchorRect.bottom;
163
164 if (rootHeight > dyBottom) {
165 LayoutParams l = scroller.getLayoutParams();
166 l.height = dyBottom;
167 }
168 }
169
170 showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up),
171 anchorRect.centerX() - xPos);
172
173 setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);
174
175 mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xPos, yPos);
176 }
177
178 /**
179 * Set animation style
180 *
181 * @param screenWidth screen width
182 * @param requestedX distance from left edge
183 * @param onTop flag to indicate where the popup should be displayed. Set
184 * TRUE if displayed on top of anchor view and vice versa
185 */
186 private void setAnimationStyle(int screenWidth, int requestedX,
187 boolean onTop) {
188 int arrowPos = requestedX - mArrowUp.getMeasuredWidth() / 2;
189
190 switch (animStyle) {
191 case ANIM_GROW_FROM_LEFT:
192 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left
193 : R.style.Animations_PopDownMenu_Left);
194 break;
195
196 case ANIM_GROW_FROM_RIGHT:
197 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right
198 : R.style.Animations_PopDownMenu_Right);
199 break;
200
201 case ANIM_GROW_FROM_CENTER:
202 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center
203 : R.style.Animations_PopDownMenu_Center);
204 break;
205
206 case ANIM_REFLECT:
207 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Reflect
208 : R.style.Animations_PopDownMenu_Reflect);
209 break;
210
211 case ANIM_AUTO:
212 if (arrowPos <= screenWidth / 4) {
213 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left
214 : R.style.Animations_PopDownMenu_Left);
215 } else if (arrowPos > screenWidth / 4
216 && arrowPos < 3 * (screenWidth / 4)) {
217 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center
218 : R.style.Animations_PopDownMenu_Center);
219 } else {
220 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right
221 : R.style.Animations_PopDownMenu_Right);
222 }
223
224 break;
225 }
226 }
227
228 /**
229 * Create action list
230 */
231 private void createActionList() {
232 View view;
233 String title;
234 Drawable icon;
235 OnClickListener listener;
236
237 for (int i = 0; i < actionList.size(); i++) {
238 title = actionList.get(i).getTitle();
239 icon = actionList.get(i).getIcon();
240 listener = actionList.get(i).getOnClickListerner();
241
242 view = getActionItem(title, icon, listener);
243
244 view.setFocusable(true);
245 view.setClickable(true);
246
247 mTrack.addView(view);
248 }
249 }
250
251 /**
252 * Get action item {@link View}
253 *
254 * @param title action item title
255 * @param icon {@link Drawable} action item icon
256 * @param listener {@link View.OnClickListener} action item listener
257 * @return action item {@link View}
258 */
259 private View getActionItem(String title, Drawable icon,
260 OnClickListener listener) {
261 LinearLayout container = (LinearLayout) inflater.inflate(
262 R.layout.action_item, null);
263
264 ImageView img = (ImageView) container.findViewById(R.id.icon);
265 TextView text = (TextView) container.findViewById(R.id.title);
266
267 if (icon != null) {
268 img.setImageDrawable(icon);
269 }
270
271 if (title != null) {
272 text.setText(title);
273 }
274
275 if (listener != null) {
276 container.setOnClickListener(listener);
277 }
278
279 return container;
280 }
281
282 /**
283 * Show arrow
284 *
285 * @param whichArrow arrow type resource id
286 * @param requestedX distance from left screen
287 */
288 private void showArrow(int whichArrow, int requestedX) {
289 final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp
290 : mArrowDown;
291 final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown
292 : mArrowUp;
293
294 final int arrowWidth = mArrowUp.getMeasuredWidth();
295
296 showArrow.setVisibility(View.VISIBLE);
297
298 ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams) showArrow
299 .getLayoutParams();
300
301 param.leftMargin = requestedX - arrowWidth / 2;
302
303 hideArrow.setVisibility(View.INVISIBLE);
304 }
305 }