6f61253b59b945033b3902dda9648c33f5618e66
[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 import eu.alefzero.owncloud.R.id;
41 import eu.alefzero.owncloud.R.layout;
42 import eu.alefzero.owncloud.R.style;
43
44 /**
45 * Popup window, shows action list as icon and text like the one in Gallery3D app.
46 *
47 * @author Lorensius. W. T
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.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 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] + mAnchor.getWidth(), location[1]
123 + mAnchor.getHeight());
124
125 createActionList();
126
127 root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
128 root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
129
130 int rootHeight = root.getMeasuredHeight();
131 int rootWidth = root.getMeasuredWidth();
132
133 int screenWidth = mWManager.getDefaultDisplay().getWidth();
134 int screenHeight = mWManager.getDefaultDisplay().getHeight();
135
136 //automatically get X coord of popup (top left)
137 if ((anchorRect.left + rootWidth) > screenWidth) {
138 xPos = anchorRect.left - (rootWidth-mAnchor.getWidth());
139 } else {
140 if (mAnchor.getWidth() > rootWidth) {
141 xPos = anchorRect.centerX() - (rootWidth/2);
142 } else {
143 xPos = anchorRect.left;
144 }
145 }
146
147 int dyTop = anchorRect.top;
148 int dyBottom = screenHeight - anchorRect.bottom;
149
150 boolean onTop = (dyTop > dyBottom) ? true : false;
151
152 if (onTop) {
153 if (rootHeight > dyTop) {
154 yPos = 15;
155 LayoutParams l = scroller.getLayoutParams();
156 l.height = dyTop - mAnchor.getHeight();
157 } else {
158 yPos = anchorRect.top - rootHeight;
159 }
160 } else {
161 yPos = anchorRect.bottom;
162
163 if (rootHeight > dyBottom) {
164 LayoutParams l = scroller.getLayoutParams();
165 l.height = dyBottom;
166 }
167 }
168
169 showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up), anchorRect.centerX()-xPos);
170
171 setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);
172
173 mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xPos, yPos);
174 }
175
176 /**
177 * Set animation style
178 *
179 * @param screenWidth screen width
180 * @param requestedX distance from left edge
181 * @param onTop flag to indicate where the popup should be displayed. Set TRUE if displayed on top of anchor view
182 * and vice versa
183 */
184 private void setAnimationStyle(int screenWidth, int requestedX, boolean onTop) {
185 int arrowPos = requestedX - mArrowUp.getMeasuredWidth()/2;
186
187 switch (animStyle) {
188 case ANIM_GROW_FROM_LEFT:
189 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left : R.style.Animations_PopDownMenu_Left);
190 break;
191
192 case ANIM_GROW_FROM_RIGHT:
193 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right : R.style.Animations_PopDownMenu_Right);
194 break;
195
196 case ANIM_GROW_FROM_CENTER:
197 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center : R.style.Animations_PopDownMenu_Center);
198 break;
199
200 case ANIM_REFLECT:
201 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Reflect : R.style.Animations_PopDownMenu_Reflect);
202 break;
203
204 case ANIM_AUTO:
205 if (arrowPos <= screenWidth/4) {
206 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left : R.style.Animations_PopDownMenu_Left);
207 } else if (arrowPos > screenWidth/4 && arrowPos < 3 * (screenWidth/4)) {
208 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center : R.style.Animations_PopDownMenu_Center);
209 } else {
210 mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right : R.style.Animations_PopDownMenu_Right);
211 }
212
213 break;
214 }
215 }
216
217 /**
218 * Create action list
219 */
220 private void createActionList() {
221 View view;
222 String title;
223 Drawable icon;
224 OnClickListener listener;
225
226 for (int i = 0; i < actionList.size(); i++) {
227 title = actionList.get(i).getTitle();
228 icon = actionList.get(i).getIcon();
229 listener = actionList.get(i).getOnClickListerner();
230
231 view = getActionItem(title, icon, listener);
232
233 view.setFocusable(true);
234 view.setClickable(true);
235
236 mTrack.addView(view);
237 }
238 }
239
240 /**
241 * Get action item {@link View}
242 *
243 * @param title action item title
244 * @param icon {@link Drawable} action item icon
245 * @param listener {@link View.OnClickListener} action item listener
246 * @return action item {@link View}
247 */
248 private View getActionItem(String title, Drawable icon, OnClickListener listener) {
249 LinearLayout container = (LinearLayout) inflater.inflate(R.layout.action_item, null);
250
251 ImageView img = (ImageView) container.findViewById(R.id.icon);
252 TextView text = (TextView) container.findViewById(R.id.title);
253
254 if (icon != null) {
255 img.setImageDrawable(icon);
256 }
257
258 if (title != null) {
259 text.setText(title);
260 }
261
262 if (listener != null) {
263 container.setOnClickListener(listener);
264 }
265
266 return container;
267 }
268
269 /**
270 * Show arrow
271 *
272 * @param whichArrow arrow type resource id
273 * @param requestedX distance from left screen
274 */
275 private void showArrow(int whichArrow, int requestedX) {
276 final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp : mArrowDown;
277 final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown : mArrowUp;
278
279 final int arrowWidth = mArrowUp.getMeasuredWidth();
280
281 showArrow.setVisibility(View.VISIBLE);
282
283 ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams)showArrow.getLayoutParams();
284
285 param.leftMargin = requestedX - arrowWidth / 2;
286
287 hideArrow.setVisibility(View.INVISIBLE);
288 }
289 }