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