| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/views/download_shelf_view.h" | 5 #include "chrome/browser/views/download_shelf_view.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "app/gfx/canvas.h" | 9 #include "app/gfx/canvas.h" |
| 10 #include "app/l10n_util.h" | 10 #include "app/l10n_util.h" |
| 11 #include "app/resource_bundle.h" | 11 #include "app/resource_bundle.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "chrome/browser/browser.h" |
| 13 #include "chrome/browser/download/download_item_model.h" | 14 #include "chrome/browser/download/download_item_model.h" |
| 14 #include "chrome/browser/download/download_manager.h" | 15 #include "chrome/browser/download/download_manager.h" |
| 15 #include "chrome/browser/tab_contents/navigation_entry.h" | 16 #include "chrome/browser/tab_contents/navigation_entry.h" |
| 16 #include "chrome/browser/tab_contents/tab_contents.h" | |
| 17 #include "chrome/browser/views/download_item_view.h" | 17 #include "chrome/browser/views/download_item_view.h" |
| 18 #include "chrome/browser/views/frame/browser_view.h" |
| 18 #include "grit/generated_resources.h" | 19 #include "grit/generated_resources.h" |
| 19 #include "grit/theme_resources.h" | 20 #include "grit/theme_resources.h" |
| 20 #include "views/background.h" | 21 #include "views/background.h" |
| 21 #include "views/controls/button/image_button.h" | 22 #include "views/controls/button/image_button.h" |
| 22 #include "views/controls/image_view.h" | 23 #include "views/controls/image_view.h" |
| 23 | 24 |
| 24 // Max number of download views we'll contain. Any time a view is added and | 25 // Max number of download views we'll contain. Any time a view is added and |
| 25 // we already have this many download views, one is removed. | 26 // we already have this many download views, one is removed. |
| 26 static const size_t kMaxDownloadViews = 15; | 27 static const size_t kMaxDownloadViews = 15; |
| 27 | 28 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 size->Enlarge(view_preferred.width(), 0); | 66 size->Enlarge(view_preferred.width(), 0); |
| 66 size->set_height(std::max(view_preferred.height(), size->height())); | 67 size->set_height(std::max(view_preferred.height(), size->height())); |
| 67 } | 68 } |
| 68 | 69 |
| 69 int CenterPosition(int size, int target_size) { | 70 int CenterPosition(int size, int target_size) { |
| 70 return std::max((target_size - size) / 2, kTopBottomPadding); | 71 return std::max((target_size - size) / 2, kTopBottomPadding); |
| 71 } | 72 } |
| 72 | 73 |
| 73 } // namespace | 74 } // namespace |
| 74 | 75 |
| 75 // static | 76 DownloadShelfView::DownloadShelfView(Browser* browser, BrowserView* parent) |
| 76 DownloadShelf* DownloadShelf::Create(TabContents* tab_contents) { | 77 : DownloadShelf(browser), parent_(parent) { |
| 77 return new DownloadShelfView(tab_contents); | 78 parent->AddChildView(this); |
| 78 } | |
| 79 | |
| 80 DownloadShelfView::DownloadShelfView(TabContents* tab_contents) | |
| 81 : DownloadShelf(tab_contents) { | |
| 82 Init(); | 79 Init(); |
| 83 } | 80 } |
| 84 | 81 |
| 85 void DownloadShelfView::Init() { | 82 void DownloadShelfView::Init() { |
| 86 ResourceBundle &rb = ResourceBundle::GetSharedInstance(); | 83 ResourceBundle &rb = ResourceBundle::GetSharedInstance(); |
| 87 arrow_image_ = new views::ImageView(); | 84 arrow_image_ = new views::ImageView(); |
| 88 arrow_image_->SetImage(rb.GetBitmapNamed(IDR_DOWNLOADS_FAVICON)); | 85 arrow_image_->SetImage(rb.GetBitmapNamed(IDR_DOWNLOADS_FAVICON)); |
| 89 AddChildView(arrow_image_); | 86 AddChildView(arrow_image_); |
| 90 | 87 |
| 91 show_all_view_ = | 88 show_all_view_ = |
| 92 new views::Link(l10n_util::GetString(IDS_SHOW_ALL_DOWNLOADS)); | 89 new views::Link(l10n_util::GetString(IDS_SHOW_ALL_DOWNLOADS)); |
| 93 show_all_view_->SetController(this); | 90 show_all_view_->SetController(this); |
| 94 AddChildView(show_all_view_); | 91 AddChildView(show_all_view_); |
| 95 | 92 |
| 96 close_button_ = new views::ImageButton(this); | 93 close_button_ = new views::ImageButton(this); |
| 97 close_button_->SetImage(views::CustomButton::BS_NORMAL, | 94 close_button_->SetImage(views::CustomButton::BS_NORMAL, |
| 98 rb.GetBitmapNamed(IDR_CLOSE_BAR)); | 95 rb.GetBitmapNamed(IDR_CLOSE_BAR)); |
| 99 close_button_->SetImage(views::CustomButton::BS_HOT, | 96 close_button_->SetImage(views::CustomButton::BS_HOT, |
| 100 rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); | 97 rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); |
| 101 close_button_->SetImage(views::CustomButton::BS_PUSHED, | 98 close_button_->SetImage(views::CustomButton::BS_PUSHED, |
| 102 rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); | 99 rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); |
| 103 AddChildView(close_button_); | 100 AddChildView(close_button_); |
| 104 set_background(views::Background::CreateSolidBackground(kBackgroundColor)); | 101 set_background(views::Background::CreateSolidBackground(kBackgroundColor)); |
| 105 | 102 |
| 106 new_item_animation_.reset(new SlideAnimation(this)); | 103 new_item_animation_.reset(new SlideAnimation(this)); |
| 107 new_item_animation_->SetSlideDuration(kNewItemAnimationDurationMs); | 104 new_item_animation_->SetSlideDuration(kNewItemAnimationDurationMs); |
| 108 | 105 |
| 109 shelf_animation_.reset(new SlideAnimation(this)); | 106 shelf_animation_.reset(new SlideAnimation(this)); |
| 110 shelf_animation_->SetSlideDuration(kShelfAnimationDurationMs); | 107 shelf_animation_->SetSlideDuration(kShelfAnimationDurationMs); |
| 111 shelf_animation_->Show(); | 108 Show(); |
| 112 | |
| 113 // The download shelf view is always owned by its tab contents. | |
| 114 SetParentOwned(false); | |
| 115 } | 109 } |
| 116 | 110 |
| 117 void DownloadShelfView::AddDownloadView(View* view) { | 111 void DownloadShelfView::AddDownloadView(View* view) { |
| 118 shelf_animation_->Show(); | 112 Show(); |
| 119 | 113 |
| 120 DCHECK(view); | 114 DCHECK(view); |
| 121 download_views_.push_back(view); | 115 download_views_.push_back(view); |
| 122 AddChildView(view); | 116 AddChildView(view); |
| 123 if (download_views_.size() > kMaxDownloadViews) | 117 if (download_views_.size() > kMaxDownloadViews) |
| 124 RemoveDownloadView(*download_views_.begin()); | 118 RemoveDownloadView(*download_views_.begin()); |
| 125 | 119 |
| 126 new_item_animation_->Reset(); | 120 new_item_animation_->Reset(); |
| 127 new_item_animation_->Show(); | 121 new_item_animation_->Show(); |
| 128 } | 122 } |
| 129 | 123 |
| 130 void DownloadShelfView::AddDownload(BaseDownloadItemModel* download_model) { | 124 void DownloadShelfView::AddDownload(BaseDownloadItemModel* download_model) { |
| 131 DownloadItemView* view = new DownloadItemView( | 125 DownloadItemView* view = new DownloadItemView( |
| 132 download_model->download(), this, download_model); | 126 download_model->download(), this, download_model); |
| 133 AddDownloadView(view); | 127 AddDownloadView(view); |
| 134 } | 128 } |
| 135 | 129 |
| 136 void DownloadShelfView::RemoveDownloadView(View* view) { | 130 void DownloadShelfView::RemoveDownloadView(View* view) { |
| 137 DCHECK(view); | 131 DCHECK(view); |
| 138 std::vector<View*>::iterator i = | 132 std::vector<View*>::iterator i = |
| 139 find(download_views_.begin(), download_views_.end(), view); | 133 find(download_views_.begin(), download_views_.end(), view); |
| 140 DCHECK(i != download_views_.end()); | 134 DCHECK(i != download_views_.end()); |
| 141 download_views_.erase(i); | 135 download_views_.erase(i); |
| 142 RemoveChildView(view); | 136 RemoveChildView(view); |
| 143 delete view; | 137 delete view; |
| 144 if (download_views_.empty()) | 138 if (download_views_.empty()) |
| 145 tab_contents_->SetDownloadShelfVisible(false); | 139 Close(); |
| 146 Layout(); | 140 Layout(); |
| 147 SchedulePaint(); | 141 SchedulePaint(); |
| 148 } | 142 } |
| 149 | 143 |
| 150 void DownloadShelfView::Paint(gfx::Canvas* canvas) { | 144 void DownloadShelfView::Paint(gfx::Canvas* canvas) { |
| 151 PaintBackground(canvas); | 145 PaintBackground(canvas); |
| 152 PaintBorder(canvas); | 146 PaintBorder(canvas); |
| 153 } | 147 } |
| 154 | 148 |
| 155 void DownloadShelfView::PaintBorder(gfx::Canvas* canvas) { | 149 void DownloadShelfView::PaintBorder(gfx::Canvas* canvas) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 178 if (animation == new_item_animation_.get()) { | 172 if (animation == new_item_animation_.get()) { |
| 179 Layout(); | 173 Layout(); |
| 180 SchedulePaint(); | 174 SchedulePaint(); |
| 181 } else if (animation == shelf_animation_.get()) { | 175 } else if (animation == shelf_animation_.get()) { |
| 182 // Force a re-layout of the parent, which will call back into | 176 // Force a re-layout of the parent, which will call back into |
| 183 // GetPreferredSize, where we will do our animation. In the case where the | 177 // GetPreferredSize, where we will do our animation. In the case where the |
| 184 // animation is hiding, we do a full resize - the fast resizing would | 178 // animation is hiding, we do a full resize - the fast resizing would |
| 185 // otherwise leave blank white areas where the shelf was and where the | 179 // otherwise leave blank white areas where the shelf was and where the |
| 186 // user's eye is. Thankfully bottom-resizing is a lot faster than | 180 // user's eye is. Thankfully bottom-resizing is a lot faster than |
| 187 // top-resizing. | 181 // top-resizing. |
| 188 tab_contents_->ToolbarSizeChanged(shelf_animation_->IsShowing()); | 182 parent_->SelectedTabToolbarSizeChanged(shelf_animation_->IsShowing()); |
| 189 } | 183 } |
| 190 } | 184 } |
| 191 | 185 |
| 192 void DownloadShelfView::AnimationEnded(const Animation *animation) { | 186 void DownloadShelfView::AnimationEnded(const Animation *animation) { |
| 193 if (animation == shelf_animation_.get()) { | 187 if (animation == shelf_animation_.get()) { |
| 194 tab_contents_->SetDownloadShelfVisible(shelf_animation_->IsShowing()); | 188 if (download_views_.empty()) |
| 189 parent_->SetDownloadShelfVisible(shelf_animation_->IsShowing()); |
| 195 } | 190 } |
| 196 } | 191 } |
| 197 | 192 |
| 198 void DownloadShelfView::Layout() { | 193 void DownloadShelfView::Layout() { |
| 199 // When the download shelf is not visible it is not parented to anything, | |
| 200 // which means it is not safe to lay out the controls, so we return early. | |
| 201 // Otherwise, we can have problems when for example the user switches to | |
| 202 // another tab (that doesn't have a download shelf) _before_ the download | |
| 203 // has started and we'll crash when calling SetVisible() below because | |
| 204 // the NativeControlContainer ctor tries to use the Container. | |
| 205 if (!GetWidget()) | |
| 206 return; | |
| 207 | |
| 208 // Let our base class layout our child views | 194 // Let our base class layout our child views |
| 209 views::View::Layout(); | 195 views::View::Layout(); |
| 210 | 196 |
| 211 // If there is not enought room to show the first download item, show the | 197 // If there is not enought room to show the first download item, show the |
| 212 // "Show all downloads" link to the left to make it more visible that there is | 198 // "Show all downloads" link to the left to make it more visible that there is |
| 213 // something to see. | 199 // something to see. |
| 214 bool show_link_only = !CanFitFirstDownloadItem(); | 200 bool show_link_only = !CanFitFirstDownloadItem(); |
| 215 | 201 |
| 216 gfx::Size image_size = arrow_image_->GetPreferredSize(); | 202 gfx::Size image_size = arrow_image_->GetPreferredSize(); |
| 217 gfx::Size close_button_size = close_button_->GetPreferredSize(); | 203 gfx::Size close_button_size = close_button_->GetPreferredSize(); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 | 277 |
| 292 gfx::Size item_size = (*download_views_.rbegin())->GetPreferredSize(); | 278 gfx::Size item_size = (*download_views_.rbegin())->GetPreferredSize(); |
| 293 return item_size.width() < available_width; | 279 return item_size.width() < available_width; |
| 294 } | 280 } |
| 295 | 281 |
| 296 void DownloadShelfView::LinkActivated(views::Link* source, int event_flags) { | 282 void DownloadShelfView::LinkActivated(views::Link* source, int event_flags) { |
| 297 ShowAllDownloads(); | 283 ShowAllDownloads(); |
| 298 } | 284 } |
| 299 | 285 |
| 300 void DownloadShelfView::ButtonPressed(views::Button* button) { | 286 void DownloadShelfView::ButtonPressed(views::Button* button) { |
| 301 shelf_animation_->Hide(); | 287 Close(); |
| 302 } | 288 } |
| 303 | 289 |
| 304 bool DownloadShelfView::IsShowing() const { | 290 bool DownloadShelfView::IsShowing() const { |
| 305 return shelf_animation_->IsShowing(); | 291 return shelf_animation_->IsShowing(); |
| 306 } | 292 } |
| 307 | 293 |
| 308 bool DownloadShelfView::IsClosing() const { | 294 bool DownloadShelfView::IsClosing() const { |
| 309 // TODO(estade): This is never called. For now just return false. | 295 // TODO(estade): This is never called. For now just return false. |
| 310 return false; | 296 return false; |
| 311 } | 297 } |
| 298 |
| 299 void DownloadShelfView::Show() { |
| 300 shelf_animation_->Show(); |
| 301 } |
| 302 |
| 303 void DownloadShelfView::Close() { |
| 304 parent_->SetDownloadShelfVisible(false); |
| 305 shelf_animation_->Hide(); |
| 306 } |
| OLD | NEW |