Home | History | Annotate | Download | only in 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.
     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.
    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