download_item_view.h revision 868fa2fe829687343ffae624259930155e16dbd8
1// Copyright (c) 2012 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 19#include <string> 20 21#include "base/basictypes.h" 22#include "base/memory/scoped_ptr.h" 23#include "base/memory/weak_ptr.h" 24#include "base/strings/string_util.h" 25#include "base/time.h" 26#include "base/timer.h" 27#include "chrome/browser/download/download_item_model.h" 28#include "chrome/browser/icon_manager.h" 29#include "chrome/common/cancelable_task_tracker.h" 30#include "content/public/browser/download_item.h" 31#include "content/public/browser/download_manager.h" 32#include "ui/base/animation/animation_delegate.h" 33#include "ui/gfx/font.h" 34#include "ui/views/context_menu_controller.h" 35#include "ui/views/controls/button/button.h" 36#include "ui/views/view.h" 37 38class DownloadShelfView; 39class DownloadShelfContextMenuView; 40 41namespace gfx { 42class Image; 43class ImageSkia; 44} 45 46namespace ui { 47class SlideAnimation; 48} 49 50namespace views { 51class Label; 52class LabelButton; 53} 54 55class DownloadItemView : public views::ButtonListener, 56 public views::View, 57 public views::ContextMenuController, 58 public content::DownloadItem::Observer, 59 public ui::AnimationDelegate { 60 public: 61 DownloadItemView(content::DownloadItem* download, 62 DownloadShelfView* parent); 63 virtual ~DownloadItemView(); 64 65 // Timer callback for handling animations 66 void UpdateDownloadProgress(); 67 void StartDownloadProgress(); 68 void StopDownloadProgress(); 69 70 // IconManager::Client interface. 71 void OnExtractIconComplete(gfx::Image* icon); 72 73 // Returns the DownloadItem model object belonging to this item. 74 content::DownloadItem* download() { return model_.download(); } 75 76 // DownloadItem::Observer methods 77 virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE; 78 virtual void OnDownloadOpened(content::DownloadItem* download) OVERRIDE; 79 virtual void OnDownloadDestroyed(content::DownloadItem* download) OVERRIDE; 80 81 // Overridden from views::View: 82 virtual void Layout() OVERRIDE; 83 virtual gfx::Size GetPreferredSize() OVERRIDE; 84 virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; 85 virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE; 86 virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE; 87 virtual void OnMouseCaptureLost() OVERRIDE; 88 virtual void OnMouseMoved(const ui::MouseEvent& event) OVERRIDE; 89 virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; 90 virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE; 91 virtual bool GetTooltipText(const gfx::Point& p, 92 string16* tooltip) const OVERRIDE; 93 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; 94 virtual void OnThemeChanged() OVERRIDE; 95 96 // Overridden from ui::EventHandler: 97 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; 98 99 // Overridden from views::ContextMenuController. 100 virtual void ShowContextMenuForView(View* source, 101 const gfx::Point& point) OVERRIDE; 102 103 // ButtonListener implementation. 104 virtual void ButtonPressed(views::Button* sender, 105 const ui::Event& event) OVERRIDE; 106 107 // ui::AnimationDelegate implementation. 108 virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE; 109 110 protected: 111 // Overridden from views::View: 112 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; 113 114 private: 115 enum State { 116 NORMAL = 0, 117 HOT, 118 PUSHED 119 }; 120 121 enum Mode { 122 NORMAL_MODE = 0, // Showing download item. 123 DANGEROUS_MODE, // Displaying the dangerous download warning. 124 MALICIOUS_MODE // Displaying the malicious download warning. 125 }; 126 127 // The image set associated with the part containing the icon and text. 128 struct BodyImageSet { 129 gfx::ImageSkia* top_left; 130 gfx::ImageSkia* left; 131 gfx::ImageSkia* bottom_left; 132 gfx::ImageSkia* top; 133 gfx::ImageSkia* center; 134 gfx::ImageSkia* bottom; 135 gfx::ImageSkia* top_right; 136 gfx::ImageSkia* right; 137 gfx::ImageSkia* bottom_right; 138 }; 139 140 // The image set associated with the drop-down button on the right. 141 struct DropDownImageSet { 142 gfx::ImageSkia* top; 143 gfx::ImageSkia* center; 144 gfx::ImageSkia* bottom; 145 }; 146 147 void OpenDownload(); 148 149 void LoadIcon(); 150 void LoadIconIfItemPathChanged(); 151 152 // Update the button colors based on the current theme. 153 void UpdateColorsFromTheme(); 154 155 // Shows the context menu at the specified location. |point| is in the view's 156 // coordinate system. 157 void ShowContextMenuImpl(const gfx::Point& point, bool is_mouse_gesture); 158 159 // Common code for handling pointer events (i.e. mouse or gesture). 160 void HandlePressEvent(const ui::LocatedEvent& event, bool active_event); 161 void HandleClickEvent(const ui::LocatedEvent& event, bool active_event); 162 163 // Convenience method to paint the 3 vertical images (bottom, middle, top) 164 // that form the background. 165 void PaintImages(gfx::Canvas* canvas, 166 const gfx::ImageSkia* top_image, 167 const gfx::ImageSkia* center_image, 168 const gfx::ImageSkia* bottom_image, 169 int x, 170 int y, 171 int height, 172 int width); 173 174 // Sets the state and triggers a repaint. 175 void SetState(State body_state, State drop_down_state); 176 177 // Whether we are in the dangerous mode. 178 bool IsShowingWarningDialog() const { 179 return mode_ == DANGEROUS_MODE || mode_ == MALICIOUS_MODE; 180 } 181 182 // Reverts from dangerous mode to normal download mode. 183 void ClearWarningDialog(); 184 185 // Start displaying the dangerous download warning or the malicious download 186 // warning. 187 void ShowWarningDialog(); 188 189 // Sets |size| with the size of the Save and Discard buttons (they have the 190 // same size). 191 gfx::Size GetButtonSize(); 192 193 // Sizes the dangerous download label to a minimum width available using 2 194 // lines. The size is computed only the first time this method is invoked 195 // and simply returned on subsequent calls. 196 void SizeLabelToMinWidth(); 197 198 // Reenables the item after it has been disabled when a user clicked it to 199 // open the downloaded file. 200 void Reenable(); 201 202 // Releases drop down button after showing a context menu. 203 void ReleaseDropDown(); 204 205 // Given |x|, returns whether |x| is within the x coordinate range of 206 // the drop-down button or not. 207 bool InDropDownButtonXCoordinateRange(int x); 208 209 // Update the accessible name to reflect the current state of the control, 210 // so that screenreaders can access the filename, status text, and 211 // dangerous download warning message (if any). 212 void UpdateAccessibleName(); 213 214 // Update the location of the drop down button. 215 void UpdateDropDownButtonPosition(); 216 217 // Show/Hide/Reset |animation| based on the state transition specified by 218 // |from| and |to|. 219 void AnimateStateTransition(State from, State to, 220 ui::SlideAnimation* animation); 221 222 // The different images used for the background. 223 BodyImageSet normal_body_image_set_; 224 BodyImageSet hot_body_image_set_; 225 BodyImageSet pushed_body_image_set_; 226 BodyImageSet dangerous_mode_body_image_set_; 227 BodyImageSet malicious_mode_body_image_set_; 228 DropDownImageSet normal_drop_down_image_set_; 229 DropDownImageSet hot_drop_down_image_set_; 230 DropDownImageSet pushed_drop_down_image_set_; 231 232 // The warning icon showns for dangerous downloads. 233 const gfx::ImageSkia* warning_icon_; 234 235 // The download shelf that owns us. 236 DownloadShelfView* shelf_; 237 238 // Elements of our particular download 239 string16 status_text_; 240 241 // The font used to print the file name and status. 242 gfx::Font font_; 243 244 // The tooltip. Only displayed when not showing a warning dialog. 245 string16 tooltip_text_; 246 247 // The current state (normal, hot or pushed) of the body and drop-down. 248 State body_state_; 249 State drop_down_state_; 250 251 // Mode of the download item view. 252 Mode mode_; 253 254 // In degrees, for downloads with no known total size. 255 int progress_angle_; 256 257 // The left and right x coordinates of the drop-down button. 258 int drop_down_x_left_; 259 int drop_down_x_right_; 260 261 // Used when we are showing the menu to show the drop-down as pressed. 262 bool drop_down_pressed_; 263 264 // The height of the box formed by the background images and its labels. 265 int box_height_; 266 267 // The y coordinate of the box formed by the background images and its labels. 268 int box_y_; 269 270 // Whether we are dragging the download button. 271 bool dragging_; 272 273 // Whether we are tracking a possible drag. 274 bool starting_drag_; 275 276 // Position that a possible drag started at. 277 gfx::Point drag_start_point_; 278 279 // For canceling an in progress icon request. 280 CancelableTaskTracker cancelable_task_tracker_; 281 282 // A model class to control the status text we display. 283 DownloadItemModel model_; 284 285 // Hover animations for our body and drop buttons. 286 scoped_ptr<ui::SlideAnimation> body_hover_animation_; 287 scoped_ptr<ui::SlideAnimation> drop_hover_animation_; 288 289 // Animation for download complete. 290 scoped_ptr<ui::SlideAnimation> complete_animation_; 291 292 // Progress animation 293 base::RepeatingTimer<DownloadItemView> progress_timer_; 294 295 // Dangerous mode buttons. 296 views::LabelButton* save_button_; 297 views::LabelButton* discard_button_; 298 299 // Dangerous mode label. 300 views::Label* dangerous_download_label_; 301 302 // Whether the dangerous mode label has been sized yet. 303 bool dangerous_download_label_sized_; 304 305 // The size of the buttons. Cached so animation works when hidden. 306 gfx::Size cached_button_size_; 307 308 // Whether we are currently disabled as part of opening the downloaded file. 309 bool disabled_while_opening_; 310 311 // The time at which this view was created. 312 base::Time creation_time_; 313 314 // Method factory used to delay reenabling of the item when opening the 315 // downloaded file. 316 base::WeakPtrFactory<DownloadItemView> weak_ptr_factory_; 317 318 // The currently running download context menu. 319 scoped_ptr<DownloadShelfContextMenuView> context_menu_; 320 321 // The name of this view as reported to assistive technology. 322 string16 accessible_name_; 323 324 // The icon loaded in the download shelf is based on the file path of the 325 // item. Store the path used, so that we can detect a change in the path 326 // and reload the icon. 327 base::FilePath last_download_item_path_; 328 329 DISALLOW_COPY_AND_ASSIGN(DownloadItemView); 330}; 331 332#endif // CHROME_BROWSER_UI_VIEWS_DOWNLOAD_DOWNLOAD_ITEM_VIEW_H__ 333