1 /* ownCloud Android client application 
   2  *   Copyright (C) 2011  Bartek Przybylski 
   3  *   Copyright (C) 2012-2013 ownCloud Inc. 
   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. 
   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. 
  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/>. 
  18 package com
.owncloud
.android
.ui
; 
  20 import android
.content
.Context
; 
  22 import android
.graphics
.Rect
; 
  23 import android
.graphics
.drawable
.Drawable
; 
  25 import android
.widget
.ImageView
; 
  26 import android
.widget
.TextView
; 
  27 import android
.widget
.LinearLayout
; 
  28 import android
.widget
.ScrollView
; 
  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
; 
  37 import java
.util
.ArrayList
; 
  39 import com
.owncloud
.android
.R
; 
  43  * Popup window, shows action list as icon and text like the one in Gallery3D 
  46  * @author Lorensius. W. T 
  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
; 
  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; 
  61     private int animStyle
; 
  62     private ViewGroup mTrack
; 
  63     private ScrollView scroller
; 
  64     private ArrayList
<ActionItem
> actionList
; 
  69      * @param anchor {@link View} on where the popup window should be displayed 
  71     public QuickAction(View anchor
) { 
  74         actionList 
= new ArrayList
<ActionItem
>(); 
  75         context 
= anchor
.getContext(); 
  76         inflater 
= (LayoutInflater
) context
 
  77                 .getSystemService(Context
.LAYOUT_INFLATER_SERVICE
); 
  79         root 
= (ViewGroup
) inflater
.inflate(R
.layout
.popup
, null
); 
  81         mArrowDown 
= (ImageView
) root
.findViewById(R
.id
.arrow_down
); 
  82         mArrowUp 
= (ImageView
) root
.findViewById(R
.id
.arrow_up
); 
  86         mTrack 
= (ViewGroup
) root
.findViewById(R
.id
.tracks
); 
  87         scroller 
= (ScrollView
) root
.findViewById(R
.id
.scroller
); 
  88         animStyle 
= ANIM_AUTO
; 
  94      * @param animStyle animation style, default is set to ANIM_AUTO 
  96     public void setAnimStyle(int animStyle
) { 
  97         this.animStyle 
= animStyle
; 
 103      * @param action {@link ActionItem} object 
 105     public void addActionItem(ActionItem action
) { 
 106         actionList
.add(action
); 
 110      * Show popup window. Popup is automatically positioned, on top or bottom of 
 119         int[] location 
= new int[2]; 
 121         mAnchor
.getLocationOnScreen(location
); 
 123         Rect anchorRect 
= new Rect(location
[0], location
[1], location
[0] 
 124                 + mAnchor
.getWidth(), location
[1] + mAnchor
.getHeight()); 
 128         root
.setLayoutParams(new LayoutParams(LayoutParams
.WRAP_CONTENT
, 
 129                 LayoutParams
.WRAP_CONTENT
)); 
 130         root
.measure(LayoutParams
.WRAP_CONTENT
, LayoutParams
.WRAP_CONTENT
); 
 132         int rootHeight 
= root
.getMeasuredHeight(); 
 133         int rootWidth 
= root
.getMeasuredWidth(); 
 135         int screenWidth 
= mWManager
.getDefaultDisplay().getWidth(); 
 136         int screenHeight 
= mWManager
.getDefaultDisplay().getHeight(); 
 138         // automatically get X coord of popup (top left) 
 139         if ((anchorRect
.left 
+ rootWidth
) > screenWidth
) { 
 140             xPos 
= anchorRect
.left 
- (rootWidth 
- mAnchor
.getWidth()); 
 142             if (mAnchor
.getWidth() > rootWidth
) { 
 143                 xPos 
= anchorRect
.centerX() - (rootWidth 
/ 2); 
 145                 xPos 
= anchorRect
.left
; 
 149         int dyTop 
= anchorRect
.top
; 
 150         int dyBottom 
= screenHeight 
- anchorRect
.bottom
; 
 152         boolean onTop 
= (dyTop 
> dyBottom
) ? true 
: false
; 
 155             if (rootHeight 
> dyTop
) { 
 157                 LayoutParams l 
= scroller
.getLayoutParams(); 
 158                 l
.height 
= dyTop 
- mAnchor
.getHeight(); 
 160                 yPos 
= anchorRect
.top 
- rootHeight
; 
 163             yPos 
= anchorRect
.bottom
; 
 165             if (rootHeight 
> dyBottom
) { 
 166                 LayoutParams l 
= scroller
.getLayoutParams(); 
 171         showArrow(((onTop
) ? R
.id
.arrow_down 
: R
.id
.arrow_up
), 
 172                 anchorRect
.centerX() - xPos
); 
 174         setAnimationStyle(screenWidth
, anchorRect
.centerX(), onTop
); 
 176         mWindow
.showAtLocation(mAnchor
, Gravity
.NO_GRAVITY
, xPos
, yPos
); 
 180      * Set animation style 
 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 
 187     private void setAnimationStyle(int screenWidth
, int requestedX
, 
 189         int arrowPos 
= requestedX 
- mArrowUp
.getMeasuredWidth() / 2; 
 192         case ANIM_GROW_FROM_LEFT
: 
 193             mWindow
.setAnimationStyle((onTop
) ? R
.style
.Animations_PopUpMenu_Left
 
 194                     : R
.style
.Animations_PopDownMenu_Left
); 
 197         case ANIM_GROW_FROM_RIGHT
: 
 198             mWindow
.setAnimationStyle((onTop
) ? R
.style
.Animations_PopUpMenu_Right
 
 199                     : R
.style
.Animations_PopDownMenu_Right
); 
 202         case ANIM_GROW_FROM_CENTER
: 
 203             mWindow
.setAnimationStyle((onTop
) ? R
.style
.Animations_PopUpMenu_Center
 
 204                     : R
.style
.Animations_PopDownMenu_Center
); 
 208             mWindow
.setAnimationStyle((onTop
) ? R
.style
.Animations_PopUpMenu_Reflect
 
 209                     : R
.style
.Animations_PopDownMenu_Reflect
); 
 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
); 
 221                 mWindow
.setAnimationStyle((onTop
) ? R
.style
.Animations_PopUpMenu_Right
 
 222                         : R
.style
.Animations_PopDownMenu_Right
); 
 232     private void createActionList() { 
 236         OnClickListener listener
; 
 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(); 
 243             view 
= getActionItem(title
, icon
, listener
); 
 245             view
.setFocusable(true
); 
 246             view
.setClickable(true
); 
 248             mTrack
.addView(view
); 
 253      * Get action item {@link View} 
 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} 
 260     private View 
getActionItem(String title
, Drawable icon
, 
 261             OnClickListener listener
) { 
 262         LinearLayout container 
= (LinearLayout
) inflater
.inflate( 
 263                 R
.layout
.action_item
, null
); 
 265         ImageView img 
= (ImageView
) container
.findViewById(R
.id
.icon
); 
 266         TextView text 
= (TextView
) container
.findViewById(R
.id
.title
); 
 269             img
.setImageDrawable(icon
); 
 276         if (listener 
!= null
) { 
 277             container
.setOnClickListener(listener
); 
 286      * @param whichArrow arrow type resource id 
 287      * @param requestedX distance from left screen 
 289     private void showArrow(int whichArrow
, int requestedX
) { 
 290         final View showArrow 
= (whichArrow 
== R
.id
.arrow_up
) ? mArrowUp
 
 292         final View hideArrow 
= (whichArrow 
== R
.id
.arrow_up
) ? mArrowDown
 
 295         final int arrowWidth 
= mArrowUp
.getMeasuredWidth(); 
 297         showArrow
.setVisibility(View
.VISIBLE
); 
 299         ViewGroup
.MarginLayoutParams param 
= (ViewGroup
.MarginLayoutParams
) showArrow
 
 302         param
.leftMargin 
= requestedX 
- arrowWidth 
/ 2; 
 304         hideArrow
.setVisibility(View
.INVISIBLE
);