Force spaces in eclipse via project specifc settings
[pub/Android/ownCloud.git] / src / eu / alefzero / owncloud / ui / QuickAction.java
1 /* ownCloud Android client application
2 * Copyright (C) 2011 Bartek Przybylski
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
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 eu.alefzero.owncloud.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 eu.alefzero.owncloud.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
69 * {@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
95 * 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
105 * {@link ActionItem} object
106 */
107 public void addActionItem(ActionItem action) {
108 actionList.add(action);
109 }
110
111 /**
112 * Show popup window. Popup is automatically positioned, on top or bottom of
113 * anchor view.
114 *
115 */
116 public void show() {
117 preShow();
118
119 int xPos, yPos;
120
121 int[] location = new int[2];
122
123 mAnchor.getLocationOnScreen(location);
124
125 Rect anchorRect = new Rect(location[0], location[1], location[0]
126 + mAnchor.getWidth(), location[1] + mAnchor.getHeight());
127
128 createActionList();
129
130 root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
131 LayoutParams.WRAP_CONTENT));
132 root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
133
134 int rootHeight = root.getMeasuredHeight();
135 int rootWidth = root.getMeasuredWidth();
136
137 int screenWidth = mWManager.getDefaultDisplay().getWidth();
138 int screenHeight = mWManager.getDefaultDisplay().getHeight();
139
140 // automatically get X coord of popup (top left)
141 if ((anchorRect.left + rootWidth) > screenWidth) {
142 xPos = anchorRect.left - (rootWidth - mAnchor.getWidth());
143 } else {
144 if (mAnchor.getWidth() > rootWidth) {
145 xPos = anchorRect.centerX() - (rootWidth / 2);
146 } else {
147 xPos = anchorRect.left;
148 }
149 }
150
151 int dyTop = anchorRect.top;
152 int dyBottom = screenHeight - anchorRect.bottom;
153
154 boolean onTop = (dyTop > dyBottom) ? true : false;
155
156 if (onTop) {
157 if (rootHeight > dyTop) {
158 yPos = 15;
159 LayoutParams l = scroller.getLayoutParams();
160 l.height = dyTop - mAnchor.getHeight();
161 } else {
162 yPos = anchorRect.top - rootHeight;
163 }
164 } else {
165 yPos = anchorRect.bottom;
166
167 if (rootHeight > dyBottom) {
168 LayoutParams l = scroller.getLayoutParams();
169 l.height = dyBottom;
170 }
171 }
172
173 showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up),
174 anchorRect.centerX() - xPos);
175
176 setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);
177
178 mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xPos, yPos);
179 }
180
181 /**
182 * Set animation style
183 *
184 * @param screenWidth
185 * screen width
186 * @param requestedX
187 * distance from left edge
188 * @param onTop
189 * flag to indicate where the popup should be displayed. Set TRUE
190 * if displayed on top of anchor view and vice versa
191 */
192 private void setAnimationStyle(int screenWidth, int requestedX,
193 boolean onTop) {
194 int arrowPos = requestedX - mArrowUp.getMeasuredWidth() / 2;
195
196 switch (animStyle) {
197 case ANIM_GROW_FROM_LEFT:
198 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left
199 : R.style.Animations_PopDownMenu_Left);
200 break;
201
202 case ANIM_GROW_FROM_RIGHT:
203 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right
204 : R.style.Animations_PopDownMenu_Right);
205 break;
206
207 case ANIM_GROW_FROM_CENTER:
208 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center
209 : R.style.Animations_PopDownMenu_Center);
210 break;
211
212 case ANIM_REFLECT:
213 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Reflect
214 : R.style.Animations_PopDownMenu_Reflect);
215 break;
216
217 case ANIM_AUTO:
218 if (arrowPos <= screenWidth / 4) {
219 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left
220 : R.style.Animations_PopDownMenu_Left);
221 } else if (arrowPos > screenWidth / 4
222 && arrowPos < 3 * (screenWidth / 4)) {
223 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center
224 : R.style.Animations_PopDownMenu_Center);
225 } else {
226 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right
227 : R.style.Animations_PopDownMenu_Right);
228 }
229
230 break;
231 }
232 }
233
234 /**
235 * Create action list
236 */
237 private void createActionList() {
238 View view;
239 String title;
240 Drawable icon;
241 OnClickListener listener;
242
243 for (int i = 0; i < actionList.size(); i++) {
244 title = actionList.get(i).getTitle();
245 icon = actionList.get(i).getIcon();
246 listener = actionList.get(i).getOnClickListerner();
247
248 view = getActionItem(title, icon, listener);
249
250 view.setFocusable(true);
251 view.setClickable(true);
252
253 mTrack.addView(view);
254 }
255 }
256
257 /**
258 * Get action item {@link View}
259 *
260 * @param title
261 * action item title
262 * @param icon
263 * {@link Drawable} action item icon
264 * @param listener
265 * {@link View.OnClickListener} action item listener
266 * @return action item {@link View}
267 */
268 private View getActionItem(String title, Drawable icon,
269 OnClickListener listener) {
270 LinearLayout container = (LinearLayout) inflater.inflate(
271 R.layout.action_item, null);
272
273 ImageView img = (ImageView) container.findViewById(R.id.icon);
274 TextView text = (TextView) container.findViewById(R.id.title);
275
276 if (icon != null) {
277 img.setImageDrawable(icon);
278 }
279
280 if (title != null) {
281 text.setText(title);
282 }
283
284 if (listener != null) {
285 container.setOnClickListener(listener);
286 }
287
288 return container;
289 }
290
291 /**
292 * Show arrow
293 *
294 * @param whichArrow
295 * arrow type resource id
296 * @param requestedX
297 * distance from left screen
298 */
299 private void showArrow(int whichArrow, int requestedX) {
300 final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp
301 : mArrowDown;
302 final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown
303 : mArrowUp;
304
305 final int arrowWidth = mArrowUp.getMeasuredWidth();
306
307 showArrow.setVisibility(View.VISIBLE);
308
309 ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams) showArrow
310 .getLayoutParams();
311
312 param.leftMargin = requestedX - arrowWidth / 2;
313
314 hideArrow.setVisibility(View.INVISIBLE);
315 }
316 }