diff options
-rw-r--r-- | chrome/browser/download/download_util.cc | 35 | ||||
-rw-r--r-- | chrome/browser/download/download_util.h | 16 | ||||
-rw-r--r-- | chrome/browser/gtk/download_item_gtk.cc | 131 | ||||
-rw-r--r-- | chrome/browser/gtk/download_item_gtk.h | 29 | ||||
-rw-r--r-- | chrome/browser/gtk/download_shelf_gtk.cc | 6 | ||||
-rw-r--r-- | chrome/chrome.gyp | 1 |
6 files changed, 176 insertions, 42 deletions
diff --git a/chrome/browser/download/download_util.cc b/chrome/browser/download/download_util.cc index 6fefb6e..82b01b9 100644 --- a/chrome/browser/download/download_util.cc +++ b/chrome/browser/download/download_util.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -8,13 +8,9 @@ #include "chrome/browser/download/download_util.h" -#include "app/gfx/chrome_canvas.h" #include "app/l10n_util.h" -#include "app/os_exchange_data.h" #include "app/resource_bundle.h" -#include "base/base_drag_source.h" #include "base/file_util.h" -#include "base/scoped_clipboard_writer.h" #include "base/string_util.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/download/download_item_model.h" @@ -25,8 +21,12 @@ #include "skia/ext/image_operations.h" #include "skia/include/SkPath.h" #include "skia/include/SkShader.h" + +#if defined(OS_WIN) +#include "app/os_exchange_data.h" +#include "base/base_drag_source.h" #include "views/drag_utils.h" -#include "views/view.h" +#endif namespace download_util { @@ -66,14 +66,14 @@ SkBitmap* g_foreground_32 = NULL; SkBitmap* g_background_32 = NULL; void PaintDownloadProgress(ChromeCanvas* canvas, +#if defined(OS_WIN) views::View* containing_view, +#endif int origin_x, int origin_y, int start_angle, int percent_done, PaintDownloadProgressSize size) { - DCHECK(containing_view); - // Load up our common bitmaps if (!g_background_16) { ResourceBundle& rb = ResourceBundle::GetSharedInstance(); @@ -89,8 +89,6 @@ void PaintDownloadProgress(ChromeCanvas* canvas, const int kProgressIconSize = (size == BIG) ? kBigProgressIconSize : kSmallProgressIconSize; - int height = background->height(); - // We start by storing the bounds of the background and foreground bitmaps // so that it is easy to mirror the bounds if the UI layout is RTL. gfx::Rect background_bounds(origin_x, origin_y, @@ -98,11 +96,13 @@ void PaintDownloadProgress(ChromeCanvas* canvas, gfx::Rect foreground_bounds(origin_x, origin_y, foreground->width(), foreground->height()); +#if defined(OS_WIN) // Mirror the positions if necessary. int mirrored_x = containing_view->MirroredLeftPointForRect(background_bounds); background_bounds.set_x(mirrored_x); mirrored_x = containing_view->MirroredLeftPointForRect(foreground_bounds); foreground_bounds.set_x(mirrored_x); +#endif // Draw the background progress image. SkPaint background_paint; @@ -165,13 +165,13 @@ void PaintDownloadProgress(ChromeCanvas* canvas, } void PaintDownloadComplete(ChromeCanvas* canvas, +#if defined(OS_WIN) views::View* containing_view, +#endif int origin_x, int origin_y, double animation_progress, PaintDownloadProgressSize size) { - DCHECK(containing_view); - // Load up our common bitmaps. if (!g_foreground_16) { ResourceBundle& rb = ResourceBundle::GetSharedInstance(); @@ -181,11 +181,13 @@ void PaintDownloadComplete(ChromeCanvas* canvas, SkBitmap* complete = (size == BIG) ? g_foreground_32 : g_foreground_16; - // Mirror the positions if necessary. gfx::Rect complete_bounds(origin_x, origin_y, complete->width(), complete->height()); +#if defined(OS_WIN) + // Mirror the positions if necessary. complete_bounds.set_x( containing_view->MirroredLeftPointForRect(complete_bounds)); +#endif // Start at full opacity, then loop back and forth five times before ending // at zero opacity. @@ -211,8 +213,9 @@ void PaintDownloadComplete(ChromeCanvas* canvas, int GetBigProgressIconSize() { static int big_progress_icon_size = 0; if (big_progress_icon_size == 0) { - std::wstring locale_size_str = - l10n_util::GetString(IDS_DOWNLOAD_BIG_PROGRESS_SIZE); + string16 locale_size_str = + WideToUTF16Hack( + l10n_util::GetString(IDS_DOWNLOAD_BIG_PROGRESS_SIZE)); bool rc = StringToInt(locale_size_str, &big_progress_icon_size); if (!rc || big_progress_icon_size < kBigProgressIconSize) { NOTREACHED(); @@ -227,6 +230,7 @@ int GetBigProgressIconOffset() { return (GetBigProgressIconSize() - kBigIconSize) / 2; } +#if defined(OS_WIN) // Download dragging void DragDownload(const DownloadItem* download, SkBitmap* icon) { DCHECK(download); @@ -244,5 +248,6 @@ void DragDownload(const DownloadItem* download, SkBitmap* icon) { DoDragDrop(data.get(), drag_source.get(), DROPEFFECT_COPY | DROPEFFECT_LINK, &effects); } +#endif } // namespace download_util diff --git a/chrome/browser/download/download_util.h b/chrome/browser/download/download_util.h index a8122ce..f3c658f 100644 --- a/chrome/browser/download/download_util.h +++ b/chrome/browser/download/download_util.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -7,16 +7,16 @@ #ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_UTIL_H_ #define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_UTIL_H_ -#include <objidl.h> - #include <set> #include <string> +#include "app/gfx/chrome_canvas.h" #include "base/basictypes.h" #include "base/task.h" -#include "views/controls/menu/menu.h" -#include "views/event.h" + +#if defined(OS_WIN) #include "views/view.h" +#endif class BaseDownloadItemModel; class DownloadItem; @@ -98,7 +98,9 @@ enum PaintDownloadProgressSize { // drawing in a right-to-left locale, we need to mirror the position of the // progress animation within the containing View. void PaintDownloadProgress(ChromeCanvas* canvas, +#if defined(OS_WIN) views::View* containing_view, +#endif int origin_x, int origin_y, int start_angle, @@ -106,12 +108,15 @@ void PaintDownloadProgress(ChromeCanvas* canvas, PaintDownloadProgressSize size); void PaintDownloadComplete(ChromeCanvas* canvas, +#if defined(OS_WIN) views::View* containing_view, +#endif int origin_x, int origin_y, double animation_progress, PaintDownloadProgressSize size); +#if defined(OS_WIN) // Drag support ---------------------------------------------------------------- // Helper function for download views to use when acting as a drag source for a @@ -122,6 +127,7 @@ void DragDownload(const DownloadItem* download, SkBitmap* icon); // Copy all executable file extensions. void InitializeExeTypes(std::set<std::string>* exe_extensions); +#endif } // namespace download_util diff --git a/chrome/browser/gtk/download_item_gtk.cc b/chrome/browser/gtk/download_item_gtk.cc index 42699e4..95db3c2 100644 --- a/chrome/browser/gtk/download_item_gtk.cc +++ b/chrome/browser/gtk/download_item_gtk.cc @@ -4,14 +4,17 @@ #include "chrome/browser/gtk/download_item_gtk.h" +#include "app/gfx/chrome_canvas.h" #include "app/gfx/chrome_font.h" #include "app/gfx/text_elider.h" #include "app/slide_animation.h" #include "base/basictypes.h" #include "base/string_util.h" +#include "base/time.h" #include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_manager.h" #include "chrome/browser/download/download_shelf.h" +#include "chrome/browser/download/download_util.h" #include "chrome/browser/gtk/download_shelf_gtk.h" #include "chrome/browser/gtk/menu_gtk.h" #include "chrome/browser/gtk/nine_box.h" @@ -31,14 +34,17 @@ const int kTextWidth = 140; // The minimum width we will ever draw the download item. Used as a lower bound // during animation. This number comes from the width of the images used to // make the download item. -const int kMinDownloadItemWidth = 13; +const int kMinDownloadItemWidth = 13 + download_util::kSmallProgressIconSize; const char* kLabelColorMarkup = "<span color='#%s'>%s</span>"; const char* kFilenameColor = "576C95"; // 87, 108, 149 const char* kStatusColor = "7B8DAE"; // 123, 141, 174 // New download item animation speed in milliseconds. -static const int kNewItemAnimationDurationMs = 800; +const int kNewItemAnimationDurationMs = 800; + +// How long the 'download complete' animation should last for. +const int kCompleteAnimationDurationMs = 2500; } // namespace @@ -139,15 +145,23 @@ NineBox* DownloadItemGtk::menu_nine_box_active_ = NULL; DownloadItemGtk::DownloadItemGtk(DownloadShelfGtk* parent_shelf, BaseDownloadItemModel* download_model) : parent_shelf_(parent_shelf), + progress_angle_(download_util::kStartAngleDegrees), download_model_(download_model), bounding_widget_(parent_shelf->GetRightBoundingWidget()) { InitNineBoxes(); body_ = gtk_button_new(); gtk_widget_set_app_paintable(body_, TRUE); - g_signal_connect(G_OBJECT(body_), "expose-event", + g_signal_connect(body_, "expose-event", G_CALLBACK(OnExpose), this); GTK_WIDGET_UNSET_FLAGS(body_, GTK_CAN_FOCUS); + // Remove internal padding on the button. + GtkRcStyle* no_padding_style = gtk_rc_style_new(); + no_padding_style->xthickness = 0; + no_padding_style->ythickness = 0; + gtk_widget_modify_style(body_, no_padding_style); + g_object_unref(no_padding_style); + name_label_ = gtk_label_new(NULL); // TODO(estade): This is at best an educated guess, since we don't actually @@ -172,14 +186,29 @@ DownloadItemGtk::DownloadItemGtk(DownloadShelfGtk* parent_shelf, GtkWidget* text_stack = gtk_vbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(text_stack), name_label_, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(text_stack), status_label_, FALSE, FALSE, 0); - gtk_container_add(GTK_CONTAINER(body_), text_stack); + + // We use a GtkFixed because we don't want it to have its own window. + // This choice of widget is not critically important though. + progress_area_ = gtk_fixed_new(); + gtk_widget_set_size_request(progress_area_, + download_util::kSmallProgressIconSize, + download_util::kSmallProgressIconSize); + gtk_widget_set_app_paintable(progress_area_, TRUE); + g_signal_connect(progress_area_, "expose-event", + G_CALLBACK(OnProgressAreaExpose), this); + + // Put the download progress icon on the left of the labels. + GtkWidget* body_hbox = gtk_hbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(body_), body_hbox); + gtk_box_pack_start(GTK_BOX(body_hbox), progress_area_, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(body_hbox), text_stack, TRUE, TRUE, 0); menu_button_ = gtk_button_new(); gtk_widget_set_app_paintable(menu_button_, TRUE); GTK_WIDGET_UNSET_FLAGS(menu_button_, GTK_CAN_FOCUS); - g_signal_connect(G_OBJECT(menu_button_), "expose-event", + g_signal_connect(menu_button_, "expose-event", G_CALLBACK(OnExpose), this); - g_signal_connect(G_OBJECT(menu_button_), "button-press-event", + g_signal_connect(menu_button_, "button-press-event", G_CALLBACK(OnMenuButtonPressEvent), this); g_object_set_data(G_OBJECT(menu_button_), "left-align-popup", reinterpret_cast<void*>(true)); @@ -205,6 +234,7 @@ DownloadItemGtk::DownloadItemGtk(DownloadShelfGtk* parent_shelf, } DownloadItemGtk::~DownloadItemGtk() { + StopDownloadProgress(); g_signal_handler_disconnect(parent_shelf_->GetHBox(), resize_handler_id_); gtk_widget_destroy(hbox_); download_model_->download()->RemoveObserver(this); @@ -218,11 +248,18 @@ void DownloadItemGtk::OnDownloadUpdated(DownloadItem* download) { parent_shelf_->RemoveDownloadItem(this); // This will delete us! return; case DownloadItem::CANCELLED: + StopDownloadProgress(); + break; case DownloadItem::COMPLETE: + StopDownloadProgress(); + complete_animation_.reset(new SlideAnimation(this)); + complete_animation_->SetSlideDuration(kCompleteAnimationDurationMs); + complete_animation_->SetTweenType(SlideAnimation::NONE); + complete_animation_->Show(); + break; case DownloadItem::IN_PROGRESS: - // TODO(estade): adjust download progress animation appropriately, once - // we have download progress animations. - NOTIMPLEMENTED(); + download_model_->download()->is_paused() ? + StopDownloadProgress() : StartDownloadProgress(); break; default: NOTREACHED(); @@ -250,15 +287,39 @@ void DownloadItemGtk::OnDownloadUpdated(DownloadItem* download) { } void DownloadItemGtk::AnimationProgressed(const Animation* animation) { - // Eventually we will show an icon and graphical download progress, but for - // now the only contents of body_ is text, so to make its size request the - // same as the width of the text. See above TODO for explanation of the - // extra 50. - int showing_width = std::max(kMinDownloadItemWidth, - static_cast<int>((kTextWidth + 50) * - new_item_animation_->GetCurrentValue())); - showing_width = std::max(showing_width, kMinDownloadItemWidth); - gtk_widget_set_size_request(body_, showing_width, -1); + if (animation == complete_animation_.get()) { + gtk_widget_queue_draw(progress_area_); + } else { + DCHECK(animation == new_item_animation_.get()); + // See above TODO for explanation of the extra 50. + int showing_width = std::max(kMinDownloadItemWidth, + static_cast<int>((kTextWidth + 50 + + download_util::kSmallProgressIconSize) * + new_item_animation_->GetCurrentValue())); + showing_width = std::max(showing_width, kMinDownloadItemWidth); + gtk_widget_set_size_request(body_, showing_width, -1); + } +} + +// Download progress animation functions. + +void DownloadItemGtk::UpdateDownloadProgress() { + progress_angle_ = (progress_angle_ + + download_util::kUnknownIncrementDegrees) % + download_util::kMaxDegrees; + gtk_widget_queue_draw(progress_area_); +} + +void DownloadItemGtk::StartDownloadProgress() { + if (progress_timer_.IsRunning()) + return; + progress_timer_.Start( + base::TimeDelta::FromMilliseconds(download_util::kProgressRateMs), this, + &DownloadItemGtk::UpdateDownloadProgress); +} + +void DownloadItemGtk::StopDownloadProgress() { + progress_timer_.Stop(); } // static @@ -337,9 +398,42 @@ gboolean DownloadItemGtk::OnExpose(GtkWidget* widget, GdkEventExpose* e, return TRUE; } +// static +gboolean DownloadItemGtk::OnProgressAreaExpose(GtkWidget* widget, + GdkEventExpose* event, DownloadItemGtk* download_item) { + // Create a transparent canvas. + ChromeCanvasPaint canvas(event, false); + if (download_item->complete_animation_.get()) { + if (download_item->complete_animation_->IsAnimating()) { + download_util::PaintDownloadComplete(&canvas, + widget->allocation.x, widget->allocation.y, + download_item->complete_animation_->GetCurrentValue(), + download_util::SMALL); + } + } else { + download_util::PaintDownloadProgress(&canvas, + widget->allocation.x, widget->allocation.y, + download_item->progress_angle_, + download_item->download_model_->download()->PercentComplete(), + download_util::SMALL); + } + + // TODO(estade): paint download icon. + return TRUE; +} + +// static gboolean DownloadItemGtk::OnMenuButtonPressEvent(GtkWidget* button, GdkEvent* event, DownloadItemGtk* item) { + // Stop any completion animation. + if (item->complete_animation_.get() && + item->complete_animation_->IsAnimating()) { + item->complete_animation_->End(); + } + + item->complete_animation_->End(); + // TODO(port): this never puts the button into the "active" state, // so this may need to be changed. See note in BrowserToolbarGtk. if (event->type == GDK_BUTTON_PRESS) { @@ -356,6 +450,7 @@ gboolean DownloadItemGtk::OnMenuButtonPressEvent(GtkWidget* button, return FALSE; } +// static void DownloadItemGtk::OnShelfResized(GtkWidget *widget, GtkAllocation *allocation, DownloadItemGtk* item) { diff --git a/chrome/browser/gtk/download_item_gtk.h b/chrome/browser/gtk/download_item_gtk.h index b7cde2d..00f1795 100644 --- a/chrome/browser/gtk/download_item_gtk.h +++ b/chrome/browser/gtk/download_item_gtk.h @@ -36,11 +36,27 @@ class DownloadItemGtk : public DownloadItem::Observer, virtual void AnimationProgressed(const Animation* animation); private: + // Functions for controlling the progress animation. + // Repaint the download progress. + void UpdateDownloadProgress(); + + // Starts a repeating timer for UpdateDownloadProgress. + void StartDownloadProgress(); + + // Stops the repeating timer. + void StopDownloadProgress(); + static void InitNineBoxes(); + // Used for the download item's body and menu button. static gboolean OnExpose(GtkWidget* widget, GdkEventExpose* e, DownloadItemGtk* download_item); + // Used for the download icon. + static gboolean OnProgressAreaExpose(GtkWidget* widget, + GdkEventExpose* e, + DownloadItemGtk* download_item); + static gboolean OnMenuButtonPressEvent(GtkWidget* button, GdkEvent* event, DownloadItemGtk* item); @@ -78,6 +94,13 @@ class DownloadItemGtk : public DownloadItem::Observer, // The widget that creates a dropdown menu when pressed. GtkWidget* menu_button_; + // The widget that contains the animation progress and the file's icon + // (as well as the complete animation). + GtkWidget* progress_area_; + + // In degrees. Only used for downloads with no known total size. + int progress_angle_; + // The menu that pops down when the user presses |menu_button_|. We do not // create this until the first time we actually need it. scoped_ptr<DownloadShelfContextMenuGtk> menu_; @@ -95,6 +118,12 @@ class DownloadItemGtk : public DownloadItem::Observer, // The animation when this item is first added to the shelf. scoped_ptr<SlideAnimation> new_item_animation_; + + // Progress animation. + base::RepeatingTimer<DownloadItemGtk> progress_timer_; + + // Animation for download complete. + scoped_ptr<SlideAnimation> complete_animation_; }; #endif // CHROME_BROWSER_GTK_DOWNLOAD_ITEM_GTK_H_ diff --git a/chrome/browser/gtk/download_shelf_gtk.cc b/chrome/browser/gtk/download_shelf_gtk.cc index d6d96ff..3eb794c 100644 --- a/chrome/browser/gtk/download_shelf_gtk.cc +++ b/chrome/browser/gtk/download_shelf_gtk.cc @@ -8,6 +8,7 @@ #include "app/resource_bundle.h" #include "base/gfx/gtk_util.h" #include "chrome/browser/download/download_item_model.h" +#include "chrome/browser/download/download_util.h" #include "chrome/browser/gtk/custom_button.h" #include "chrome/browser/gtk/download_item_gtk.h" #include "chrome/browser/gtk/link_button_gtk.h" @@ -18,9 +19,8 @@ namespace { -// The height of the download items. Should be at least 28, as that is the -// minimum height of their nineboxes. -const int kDownloadItemHeight = 38; +// The height of the download items. +const int kDownloadItemHeight = download_util::kSmallProgressIconSize; // Padding between the download widgets. const int kDownloadItemPadding = 10; diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index bf4e134..0815db4 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -1543,7 +1543,6 @@ 'browser/debugger/debugger_shell_stubs.cc', # Windows-specific files. 'browser/download/download_exe.cc', - 'browser/download/download_util.cc', ], }], ['OS=="mac"', { |