• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.documentsui.dirlist;
18 
19 import static com.android.documentsui.base.DocumentInfo.getCursorString;
20 
21 import android.annotation.Nullable;
22 import android.content.Context;
23 import android.database.Cursor;
24 import android.graphics.Rect;
25 import android.text.format.Formatter;
26 import android.view.View;
27 import android.view.ViewGroup;
28 import android.widget.ImageView;
29 import android.widget.LinearLayout;
30 import android.widget.TextView;
31 
32 import com.android.documentsui.R;
33 import com.android.documentsui.base.DocumentInfo;
34 import com.android.documentsui.base.Events.InputEvent;
35 import com.android.documentsui.base.Lookup;
36 import com.android.documentsui.base.Shared;
37 import com.android.documentsui.roots.RootCursorWrapper;
38 
39 final class ListDocumentHolder extends DocumentHolder {
40 
41     private final TextView mTitle;
42     private final @Nullable LinearLayout mDetails;  // Container of date/size/summary
43     private final TextView mDate;
44     private final TextView mSize;
45     private final TextView mType;
46     private final TextView mSummary;
47     private final ImageView mIconMime;
48     private final ImageView mIconThumb;
49     private final ImageView mIconCheck;
50     private final View mIconLayout;
51 
52     private final IconHelper mIconHelper;
53     private final Lookup<String, String> mFileTypeLookup;
54     // This is used in as a convenience in our bind method.
55     private final DocumentInfo mDoc;
56 
ListDocumentHolder(Context context, ViewGroup parent, IconHelper iconHelper, Lookup<String, String> fileTypeLookup)57     public ListDocumentHolder(Context context, ViewGroup parent, IconHelper iconHelper,
58             Lookup<String, String> fileTypeLookup) {
59         super(context, parent, R.layout.item_doc_list);
60 
61         mIconLayout = itemView.findViewById(android.R.id.icon);
62         mIconMime = (ImageView) itemView.findViewById(R.id.icon_mime);
63         mIconThumb = (ImageView) itemView.findViewById(R.id.icon_thumb);
64         mIconCheck = (ImageView) itemView.findViewById(R.id.icon_check);
65         mTitle = (TextView) itemView.findViewById(android.R.id.title);
66         mSummary = (TextView) itemView.findViewById(android.R.id.summary);
67         mSize = (TextView) itemView.findViewById(R.id.size);
68         mDate = (TextView) itemView.findViewById(R.id.date);
69         mType = (TextView) itemView.findViewById(R.id.file_type);
70         // Warning: mDetails view doesn't exists in layout-sw720dp-land layout
71         mDetails = (LinearLayout) itemView.findViewById(R.id.line2);
72 
73         mIconHelper = iconHelper;
74         mFileTypeLookup = fileTypeLookup;
75         mDoc = new DocumentInfo();
76     }
77 
78     @Override
setSelected(boolean selected, boolean animate)79     public void setSelected(boolean selected, boolean animate) {
80         // We always want to make sure our check box disappears if we're not selected,
81         // even if the item is disabled. But it should be an error (see assert below)
82         // to be set to selected && be disabled.
83         float checkAlpha = selected ? 1f : 0f;
84         if (animate) {
85             fade(mIconCheck, checkAlpha).start();
86         } else {
87             mIconCheck.setAlpha(checkAlpha);
88         }
89 
90         if (!itemView.isEnabled()) {
91             assert(!selected);
92             return;
93         }
94 
95         super.setSelected(selected, animate);
96 
97         if (animate) {
98             fade(mIconMime, 1f - checkAlpha).start();
99             fade(mIconThumb, 1f - checkAlpha).start();
100         } else {
101             mIconMime.setAlpha(1f - checkAlpha);
102             mIconThumb.setAlpha(1f - checkAlpha);
103         }
104     }
105 
106     @Override
setEnabled(boolean enabled)107     public void setEnabled(boolean enabled) {
108         super.setEnabled(enabled);
109 
110         // Text colors enabled/disabled is handle via a color set.
111         final float imgAlpha = enabled ? 1f : DISABLED_ALPHA;
112         mIconMime.setAlpha(imgAlpha);
113         mIconThumb.setAlpha(imgAlpha);
114     }
115 
116     @Override
isInDragHotspot(InputEvent event)117     public boolean isInDragHotspot(InputEvent event) {
118         // If itemView is activated = selected, then whole region is interactive
119         if (itemView.isActivated()) {
120             return true;
121         }
122 
123         // Do everything in global coordinates - it makes things simpler.
124         int[] coords = new int[2];
125         mIconLayout.getLocationOnScreen(coords);
126 
127         Rect textBounds = new Rect();
128         mTitle.getPaint().getTextBounds(
129                 mTitle.getText().toString(), 0, mTitle.getText().length(), textBounds);
130 
131         Rect rect = new Rect(
132                 coords[0],
133                 coords[1],
134                 coords[0] + mIconLayout.getWidth() + textBounds.width(),
135                 coords[1] + Math.max(mIconLayout.getHeight(), textBounds.height()));
136 
137         // If the tap occurred inside icon or the text, these are interactive spots.
138         return rect.contains((int) event.getRawX(), (int) event.getRawY());
139     }
140 
141     @Override
isOverDocIcon(InputEvent event)142     public boolean isOverDocIcon(InputEvent event) {
143         Rect iconRect = new Rect();
144         mIconLayout.getGlobalVisibleRect(iconRect);
145 
146         return iconRect.contains((int) event.getRawX(), (int) event.getRawY());
147     }
148 
149     /**
150      * Bind this view to the given document for display.
151      * @param cursor Pointing to the item to be bound.
152      * @param modelId The model ID of the item.
153      */
154     @Override
bind(Cursor cursor, String modelId)155     public void bind(Cursor cursor, String modelId) {
156         assert(cursor != null);
157 
158         mModelId = modelId;
159 
160         mDoc.updateFromCursor(cursor, getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY));
161 
162         mIconHelper.stopLoading(mIconThumb);
163 
164         mIconMime.animate().cancel();
165         mIconMime.setAlpha(1f);
166         mIconThumb.animate().cancel();
167         mIconThumb.setAlpha(0f);
168 
169         mIconHelper.load(mDoc, mIconThumb, mIconMime, null);
170 
171         mTitle.setText(mDoc.displayName, TextView.BufferType.SPANNABLE);
172         mTitle.setVisibility(View.VISIBLE);
173 
174 
175         boolean hasDetails = false;
176         if (mDoc.isDirectory()) {
177             // Note, we don't show any details for any directory...ever.
178             hasDetails = false;
179         } else {
180             if (mDoc.summary != null) {
181                 hasDetails = true;
182                 mSummary.setText(mDoc.summary);
183                 mSummary.setVisibility(View.VISIBLE);
184             } else {
185                 mSummary.setVisibility(View.INVISIBLE);
186             }
187 
188             if (mDoc.lastModified > 0) {
189                 hasDetails = true;
190                 mDate.setText(Shared.formatTime(mContext, mDoc.lastModified));
191             } else {
192                 mDate.setText(null);
193             }
194 
195             if (mDoc.size > -1) {
196                 hasDetails = true;
197                 mSize.setVisibility(View.VISIBLE);
198                 mSize.setText(Formatter.formatFileSize(mContext, mDoc.size));
199             } else {
200                 mSize.setVisibility(View.INVISIBLE);
201             }
202 
203             mType.setText(mFileTypeLookup.lookup(mDoc.mimeType));
204         }
205 
206         // mDetails view doesn't exists in layout-sw720dp-land layout
207         if (mDetails != null) {
208             mDetails.setVisibility(hasDetails ? View.VISIBLE : View.GONE);
209         }
210 
211         // TODO: Add document debug info
212         // Call includeDebugInfo
213     }
214 }
215