summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-06 00:59:22 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-06 00:59:22 +0000
commit001c3c0253b58b7d9ce84d90be76a0f56645688d (patch)
tree257ad61b1d394e19284907857b30d811d26f3716 /chrome/browser/gtk
parent6b9980acad8f549a03b3c1df844fb803ac2439c8 (diff)
downloadchromium_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.cc113
-rw-r--r--chrome/browser/gtk/download_item_gtk.h9
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_;