• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // A ChromeView that implements one download on the Download shelf.
6 // Each DownloadItemView contains an application icon, a text label
7 // indicating the download's file name, a text label indicating the
8 // download's status (such as the number of bytes downloaded so far)
9 // and a button for canceling an in progress download, or opening
10 // the completed download.
11 //
12 // The DownloadItemView lives in the Browser, and has a corresponding
13 // DownloadController that receives / writes data which lives in the
14 // Renderer.
15 
16 #ifndef CHROME_BROWSER_UI_VIEWS_DOWNLOAD_DOWNLOAD_ITEM_VIEW_H__
17 #define CHROME_BROWSER_UI_VIEWS_DOWNLOAD_DOWNLOAD_ITEM_VIEW_H__
18 #pragma once
19 
20 #include <string>
21 
22 #include "base/basictypes.h"
23 #include "base/memory/scoped_ptr.h"
24 #include "base/time.h"
25 #include "base/timer.h"
26 #include "chrome/browser/download/download_item.h"
27 #include "chrome/browser/download/download_manager.h"
28 #include "chrome/browser/icon_manager.h"
29 #include "content/browser/cancelable_request.h"
30 #include "ui/base/animation/animation_delegate.h"
31 #include "ui/gfx/font.h"
32 #include "views/controls/button/button.h"
33 #include "views/events/event.h"
34 #include "views/view.h"
35 
36 class BaseDownloadItemModel;
37 class DownloadShelfView;
38 class SkBitmap;
39 class DownloadShelfContextMenuWin;
40 
41 namespace gfx {
42 class Image;
43 }
44 
45 namespace ui {
46 class SlideAnimation;
47 }
48 
49 namespace views {
50 class Label;
51 class NativeButton;
52 }
53 
54 class DownloadItemView : public views::ButtonListener,
55                          public views::View,
56                          public DownloadItem::Observer,
57                          public ui::AnimationDelegate {
58  public:
59   DownloadItemView(DownloadItem* download,
60                    DownloadShelfView* parent,
61                    BaseDownloadItemModel* model);
62   virtual ~DownloadItemView();
63 
64   // Timer callback for handling animations
65   void UpdateDownloadProgress();
66   void StartDownloadProgress();
67   void StopDownloadProgress();
68 
69   // IconManager::Client interface.
70   void OnExtractIconComplete(IconManager::Handle handle, gfx::Image* icon);
71 
72   // Returns the DownloadItem model object belonging to this item.
download()73   DownloadItem* download() const { return download_; }
74 
75   // DownloadObserver method
76   virtual void OnDownloadUpdated(DownloadItem* download) OVERRIDE;
77   virtual void OnDownloadOpened(DownloadItem* download) OVERRIDE;
78 
79   // Overridden from views::View:
80   virtual void Layout() OVERRIDE;
81   virtual gfx::Size GetPreferredSize() OVERRIDE;
82   virtual bool OnMousePressed(const views::MouseEvent& event) OVERRIDE;
83   virtual bool OnMouseDragged(const views::MouseEvent& event) OVERRIDE;
84   virtual void OnMouseReleased(const views::MouseEvent& event) OVERRIDE;
85   virtual void OnMouseCaptureLost() OVERRIDE;
86   virtual void OnMouseMoved(const views::MouseEvent& event) OVERRIDE;
87   virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE;
88   virtual bool OnKeyPressed(const views::KeyEvent& event) OVERRIDE;
89   virtual bool GetTooltipText(const gfx::Point& p,
90                               std::wstring* tooltip) OVERRIDE;
91   virtual void ShowContextMenu(const gfx::Point& p,
92                                bool is_mouse_gesture) OVERRIDE;
93   virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
94 
95   // ButtonListener implementation.
96   virtual void ButtonPressed(views::Button* sender,
97                              const views::Event& event) OVERRIDE;
98 
99   // ui::AnimationDelegate implementation.
100   virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE;
101 
102  protected:
103   // Overridden from views::View:
104   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
105 
106  private:
107   enum State {
108     NORMAL = 0,
109     HOT,
110     PUSHED,
111     DANGEROUS
112   };
113 
114   // The image set associated with the part containing the icon and text.
115   struct BodyImageSet {
116     SkBitmap* top_left;
117     SkBitmap* left;
118     SkBitmap* bottom_left;
119     SkBitmap* top;
120     SkBitmap* center;
121     SkBitmap* bottom;
122     SkBitmap* top_right;
123     SkBitmap* right;
124     SkBitmap* bottom_right;
125   };
126 
127   // The image set associated with the drop-down button on the right.
128   struct DropDownImageSet {
129     SkBitmap* top;
130     SkBitmap* center;
131     SkBitmap* bottom;
132   };
133 
134   void OpenDownload();
135 
136   void LoadIcon();
137 
138   // Convenience method to paint the 3 vertical bitmaps (bottom, middle, top)
139   // that form the background.
140   void PaintBitmaps(gfx::Canvas* canvas,
141                     const SkBitmap* top_bitmap,
142                     const SkBitmap* center_bitmap,
143                     const SkBitmap* bottom_bitmap,
144                     int x,
145                     int y,
146                     int height,
147                     int width);
148 
149   // Sets the state and triggers a repaint.
150   void SetState(State body_state, State drop_down_state);
151 
152   // Whether we are in the dangerous mode.
IsDangerousMode()153   bool IsDangerousMode() { return body_state_ == DANGEROUS; }
154 
155   // Reverts from dangerous mode to normal download mode.
156   void ClearDangerousMode();
157 
158   // Sets |size| with the size of the Save and Discard buttons (they have the
159   // same size).
160   gfx::Size GetButtonSize();
161 
162   // Sizes the dangerous download label to a minimum width available using 2
163   // lines.  The size is computed only the first time this method is invoked
164   // and simply returned on subsequent calls.
165   void SizeLabelToMinWidth();
166 
167   // Reenables the item after it has been disabled when a user clicked it to
168   // open the downloaded file.
169   void Reenable();
170 
171   // Given |x|, returns whether |x| is within the x coordinate range of
172   // the drop-down button or not.
173   bool InDropDownButtonXCoordinateRange(int x);
174 
175   // Update the accessible name to reflect the current state of the control,
176   // so that screenreaders can access the filename, status text, and
177   // dangerous download warning message (if any).
178   void UpdateAccessibleName();
179 
180   // The different images used for the background.
181   BodyImageSet normal_body_image_set_;
182   BodyImageSet hot_body_image_set_;
183   BodyImageSet pushed_body_image_set_;
184   BodyImageSet dangerous_mode_body_image_set_;
185   DropDownImageSet normal_drop_down_image_set_;
186   DropDownImageSet hot_drop_down_image_set_;
187   DropDownImageSet pushed_drop_down_image_set_;
188 
189   // The warning icon showns for dangerous downloads.
190   const SkBitmap* warning_icon_;
191 
192   // The model we query for display information
193   DownloadItem* download_;
194 
195   // Our parent view that owns us.
196   DownloadShelfView* parent_;
197 
198   // Elements of our particular download
199   std::wstring status_text_;
200   bool show_status_text_;
201 
202   // The font used to print the file name and status.
203   gfx::Font font_;
204 
205   // The tooltip.
206   std::wstring tooltip_text_;
207 
208   // The current state (normal, hot or pushed) of the body and drop-down.
209   State body_state_;
210   State drop_down_state_;
211 
212   // In degrees, for downloads with no known total size.
213   int progress_angle_;
214 
215   // The left and right x coordinates of the drop-down button.
216   int drop_down_x_left_;
217   int drop_down_x_right_;
218 
219   // Used when we are showing the menu to show the drop-down as pressed.
220   bool drop_down_pressed_;
221 
222   // The height of the box formed by the background images and its labels.
223   int box_height_;
224 
225   // The y coordinate of the box formed by the background images and its labels.
226   int box_y_;
227 
228   // Whether we are dragging the download button.
229   bool dragging_;
230 
231   // Whether we are tracking a possible drag.
232   bool starting_drag_;
233 
234   // Position that a possible drag started at.
235   gfx::Point drag_start_point_;
236 
237   // For canceling an in progress icon request.
238   CancelableRequestConsumerT<int, 0> icon_consumer_;
239 
240   // A model class to control the status text we display and the cancel
241   // behavior.
242   // This class owns the pointer.
243   scoped_ptr<BaseDownloadItemModel> model_;
244 
245   // Hover animations for our body and drop buttons.
246   scoped_ptr<ui::SlideAnimation> body_hover_animation_;
247   scoped_ptr<ui::SlideAnimation> drop_hover_animation_;
248 
249   // Animation for download complete.
250   scoped_ptr<ui::SlideAnimation> complete_animation_;
251 
252   // Progress animation
253   base::RepeatingTimer<DownloadItemView> progress_timer_;
254 
255   // Dangerous mode buttons.
256   views::NativeButton* save_button_;
257   views::NativeButton* discard_button_;
258 
259   // Dangerous mode label.
260   views::Label* dangerous_download_label_;
261 
262   // Whether the dangerous mode label has been sized yet.
263   bool dangerous_download_label_sized_;
264 
265   // The size of the buttons.  Cached so animation works when hidden.
266   gfx::Size cached_button_size_;
267 
268   // Whether we are currently disabled as part of opening the downloaded file.
269   bool disabled_while_opening_;
270 
271   // The time at which this view was created.
272   base::Time creation_time_;
273 
274   // Method factory used to delay reenabling of the item when opening the
275   // downloaded file.
276   ScopedRunnableMethodFactory<DownloadItemView> reenable_method_factory_;
277 
278   // The currently running download context menu.
279   scoped_ptr<DownloadShelfContextMenuWin> context_menu_;
280 
281   // If non-NULL, set to true when this object is deleted.
282   // (Used when showing the context menu as it runs an inner message loop that
283   // might delete us).
284   bool* deleted_;
285 
286   // The name of this view as reported to assistive technology.
287   string16 accessible_name_;
288 
289   DISALLOW_COPY_AND_ASSIGN(DownloadItemView);
290 };
291 
292 #endif  // CHROME_BROWSER_UI_VIEWS_DOWNLOAD_DOWNLOAD_ITEM_VIEW_H__
293