diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-06 00:59:22 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-06 00:59:22 +0000 |
commit | 001c3c0253b58b7d9ce84d90be76a0f56645688d (patch) | |
tree | 257ad61b1d394e19284907857b30d811d26f3716 /chrome/browser/gtk | |
parent | 6b9980acad8f549a03b3c1df844fb803ac2439c8 (diff) | |
download | chromium_src-001c3c0253b58b7d9ce84d90be76a0f56645688d.zip chromium_src-001c3c0253b58b7d9ce84d90be76a0f56645688d.tar.gz chromium_src-001c3c0253b58b7d9ce84d90be76a0f56645688d.tar.bz2 |
Create a dropdown menu for the GTK download shelf.
Review URL: http://codereview.chromium.org/39236
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@11074 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk')
-rw-r--r-- | chrome/browser/gtk/download_item_gtk.cc | 113 | ||||
-rw-r--r-- | chrome/browser/gtk/download_item_gtk.h | 9 |
2 files changed, 121 insertions, 1 deletions
diff --git a/chrome/browser/gtk/download_item_gtk.cc b/chrome/browser/gtk/download_item_gtk.cc index 7e6c4f6..240ac9f 100644 --- a/chrome/browser/gtk/download_item_gtk.cc +++ b/chrome/browser/gtk/download_item_gtk.cc @@ -7,9 +7,11 @@ #include "base/basictypes.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/gtk/menu_gtk.h" #include "chrome/browser/gtk/nine_box.h" #include "chrome/common/resource_bundle.h" - +#include "grit/generated_resources.h" #include "grit/theme_resources.h" namespace { @@ -20,6 +22,92 @@ const int kMenuButtonWidth = 16; } // namespace +// DownloadShelfContextMenuGtk ------------------------------------------------- + +class DownloadShelfContextMenuGtk : public DownloadShelfContextMenu, + public MenuGtk::Delegate { + public: + // The constructor creates the menu and immediately pops it up. + // |model| is the download item model associated with this context menu, + // |widget| is the button that popped up this context menu, and |e| is + // the button press event that caused this menu to be created. + DownloadShelfContextMenuGtk(BaseDownloadItemModel* model) + : DownloadShelfContextMenu(model), + menu_is_for_complete_download_(false) { + } + + ~DownloadShelfContextMenuGtk() { + } + + void Popup(GtkWidget* widget, GdkEvent* event) { + // Create the menu if we have not created it yet or we created it for + // an in-progress download that has since completed. + bool download_is_complete = download_->state() == DownloadItem::COMPLETE; + if (menu_.get() == NULL || + (download_is_complete && !menu_is_for_complete_download_)) { + menu_.reset(new MenuGtk(this, download_is_complete ? + finished_download_menu : in_progress_download_menu)); + menu_is_for_complete_download_ = download_is_complete; + } + menu_->Popup(widget, event); + } + + // MenuGtk::Delegate implementation ------------------------------------------ + virtual bool IsCommandEnabled(int id) const { + return IsItemCommandEnabled(id); + } + + virtual bool IsItemChecked(int id) const { + return ItemIsChecked(id); + } + + virtual void ExecuteCommand(int id) { + return ExecuteItemCommand(id); + } + + private: + // The menu we show on Popup(). We keep a pointer to it for a couple reasons: + // * we don't want to have to recreate the menu every time it's popped up. + // * we have to keep it in scope for longer than the duration of Popup(), or + // completing the user-selected action races against the menu's + // destruction. + scoped_ptr<MenuGtk> menu_; + + // If true, the MenuGtk in |menu_| refers to a finished download menu. + bool menu_is_for_complete_download_; + + // We show slightly different menus if the download is in progress vs. if the + // download has finished. + static MenuCreateMaterial in_progress_download_menu[]; + + static MenuCreateMaterial finished_download_menu[]; +}; + +MenuCreateMaterial DownloadShelfContextMenuGtk::finished_download_menu[] = { + { MENU_NORMAL, OPEN_WHEN_COMPLETE, IDS_DOWNLOAD_MENU_OPEN, 0, NULL }, + { MENU_CHECKBOX, ALWAYS_OPEN_TYPE, IDS_DOWNLOAD_MENU_ALWAYS_OPEN_TYPE, + 0, NULL}, + { MENU_SEPARATOR, 0, 0, 0, NULL }, + { MENU_NORMAL, SHOW_IN_FOLDER, IDS_DOWNLOAD_LINK_SHOW, 0, NULL}, + { MENU_SEPARATOR, 0, 0, 0, NULL }, + { MENU_NORMAL, CANCEL, IDS_DOWNLOAD_MENU_CANCEL, 0, NULL}, + { MENU_END, 0, 0, 0, NULL }, +}; + +MenuCreateMaterial DownloadShelfContextMenuGtk::in_progress_download_menu[] = { + { MENU_CHECKBOX, OPEN_WHEN_COMPLETE, IDS_DOWNLOAD_MENU_OPEN_WHEN_COMPLETE, + 0, NULL }, + { MENU_CHECKBOX, ALWAYS_OPEN_TYPE, IDS_DOWNLOAD_MENU_ALWAYS_OPEN_TYPE, + 0, NULL}, + { MENU_SEPARATOR, 0, 0, 0, NULL }, + { MENU_NORMAL, SHOW_IN_FOLDER, IDS_DOWNLOAD_LINK_SHOW, 0, NULL}, + { MENU_SEPARATOR, 0, 0, 0, NULL }, + { MENU_NORMAL, CANCEL, IDS_DOWNLOAD_MENU_CANCEL, 0, NULL}, + { MENU_END, 0, 0, 0, NULL }, +}; + +// DownloadItemGtk ------------------------------------------------------------- + NineBox* DownloadItemGtk::body_nine_box_normal_ = NULL; NineBox* DownloadItemGtk::body_nine_box_prelight_ = NULL; NineBox* DownloadItemGtk::body_nine_box_active_ = NULL; @@ -50,6 +138,10 @@ DownloadItemGtk::DownloadItemGtk(BaseDownloadItemModel* download_model, GTK_WIDGET_UNSET_FLAGS(menu_button_, GTK_CAN_FOCUS); g_signal_connect(G_OBJECT(menu_button_), "expose-event", G_CALLBACK(OnExpose), this); + g_signal_connect(G_OBJECT(menu_button_), "button-press-event", + G_CALLBACK(OnMenuButtonPressEvent), this); + g_object_set_data(G_OBJECT(menu_button_), "left-align-popup", + reinterpret_cast<void*>(true)); gtk_widget_set_size_request(menu_button_, kMenuButtonWidth, 0); hbox_ = gtk_hbox_new(FALSE, 0); @@ -180,3 +272,22 @@ gboolean DownloadItemGtk::OnExpose(GtkWidget* widget, GdkEventExpose* e, return TRUE; } +gboolean DownloadItemGtk::OnMenuButtonPressEvent(GtkWidget* button, + GdkEvent* event, + DownloadItemGtk* item) { + // 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) { + GdkEventButton* event_button = reinterpret_cast<GdkEventButton*>(event); + if (event_button->button == 1) { + if (item->menu_.get() == NULL) { + item->menu_.reset(new DownloadShelfContextMenuGtk( + item->download_model_.get())); + } + item->menu_->Popup(button, event); + } + } + + return FALSE; +} + diff --git a/chrome/browser/gtk/download_item_gtk.h b/chrome/browser/gtk/download_item_gtk.h index d65f840..5044a25 100644 --- a/chrome/browser/gtk/download_item_gtk.h +++ b/chrome/browser/gtk/download_item_gtk.h @@ -10,6 +10,7 @@ #include "base/scoped_ptr.h" class BaseDownloadItemModel; +class DownloadShelfContextMenuGtk; class NineBox; class DownloadItemGtk { @@ -28,6 +29,10 @@ class DownloadItemGtk { static gboolean OnExpose(GtkWidget* widget, GdkEventExpose* e, DownloadItemGtk* download_item); + static gboolean OnMenuButtonPressEvent(GtkWidget* button, + GdkEvent* event, + DownloadItemGtk* item); + // Nineboxes for the body area. static NineBox* body_nine_box_normal_; static NineBox* body_nine_box_prelight_; @@ -48,6 +53,10 @@ class DownloadItemGtk { // The widget that creates a dropdown menu when pressed. GtkWidget* menu_button_; + // 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_; + // The download item model we represent. scoped_ptr<BaseDownloadItemModel> download_model_; |