diff options
Diffstat (limited to 'chrome/browser/gtk')
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.cc | 12 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.h | 4 | ||||
-rw-r--r-- | chrome/browser/gtk/custom_button.cc | 11 | ||||
-rw-r--r-- | chrome/browser/gtk/custom_button.h | 6 | ||||
-rw-r--r-- | chrome/browser/gtk/download_shelf_gtk.cc | 9 | ||||
-rw-r--r-- | chrome/browser/gtk/find_bar_gtk.cc | 13 | ||||
-rw-r--r-- | chrome/browser/gtk/infobar_container_gtk.cc | 118 | ||||
-rw-r--r-- | chrome/browser/gtk/infobar_container_gtk.h | 68 | ||||
-rw-r--r-- | chrome/browser/gtk/infobar_gtk.cc | 73 | ||||
-rw-r--r-- | chrome/browser/gtk/infobar_gtk.h | 66 |
10 files changed, 359 insertions, 21 deletions
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index 7613f69..b1f3f87 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -21,6 +21,7 @@ #include "chrome/browser/find_bar_controller.h" #include "chrome/browser/gtk/bookmark_bar_gtk.h" #include "chrome/browser/gtk/browser_toolbar_gtk.h" +#include "chrome/browser/gtk/infobar_container_gtk.h" #include "chrome/browser/gtk/find_bar_gtk.h" #include "chrome/browser/gtk/status_bubble_gtk.h" #include "chrome/browser/gtk/tab_contents_container_gtk.h" @@ -198,6 +199,11 @@ BrowserWindowGtk::BrowserWindowGtk(Browser* browser) bookmark_bar_.reset(new BookmarkBarGtk(browser_->profile(), browser_.get())); bookmark_bar_->AddBookmarkbarToBox(content_vbox_); + infobar_container_.reset(new InfoBarContainerGtk(this)); + gtk_box_pack_start(GTK_BOX(content_vbox_), + infobar_container_->widget(), + FALSE, FALSE, 0); + // Insert a border between the toolbar and the web contents. GtkWidget* border = gtk_event_box_new(); gtk_widget_set_size_request(border, -1, 1); @@ -501,8 +507,7 @@ void BrowserWindowGtk::TabDetachedAt(TabContents* contents, int index) { // the model has already removed |contents| from its list, so // browser_->GetSelectedTabContents() will return NULL or something else. if (index == browser_->tabstrip_model()->selected_index()) { - // TODO(port): Uncoment this line when we get infobars. - // infobar_container_->ChangeTabContents(NULL); + infobar_container_->ChangeTabContents(NULL); contents_container_->SetTabContents(NULL); // When dragging the last TabContents out of a window there is no selection @@ -523,8 +528,7 @@ void BrowserWindowGtk::TabSelectedAt(TabContents* old_contents, // Update various elements that are interested in knowing the current // TabContents. - // TOOD(port): Un-comment this line when we get infobars. - // infobar_container_->ChangeTabContents(new_contents); + infobar_container_->ChangeTabContents(new_contents); contents_container_->SetTabContents(new_contents); new_contents->DidBecomeSelected(); diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h index 4305dac..bc9f697 100644 --- a/chrome/browser/gtk/browser_window_gtk.h +++ b/chrome/browser/gtk/browser_window_gtk.h @@ -19,6 +19,7 @@ class BookmarkBarGtk; class BrowserToolbarGtk; class FindBarController; +class InfoBarContainerGtk; class LocationBar; class NineBox; class StatusBubbleGtk; @@ -169,6 +170,9 @@ class BrowserWindowGtk : public BrowserWindow, // The tab strip. Always non-NULL. scoped_ptr<TabStripGtk> tabstrip_; + // The container for info bars. Always non-NULL. + scoped_ptr<InfoBarContainerGtk> infobar_container_; + // When it goes out of scope during our destruction, |method_factory_| will // cancel its pending tasks (which depend on us still existing). ScopedRunnableMethodFactory<BrowserWindowGtk> method_factory_; diff --git a/chrome/browser/gtk/custom_button.cc b/chrome/browser/gtk/custom_button.cc index e3d45d2..150d29f 100644 --- a/chrome/browser/gtk/custom_button.cc +++ b/chrome/browser/gtk/custom_button.cc @@ -66,6 +66,17 @@ gboolean CustomDrawButton::OnExpose(GtkWidget* widget, GdkEventExpose* e, return TRUE; } +// static +CustomDrawButton* CustomDrawButton::AddBarCloseButton(GtkWidget* hbox) { + CustomDrawButton* rv = new CustomDrawButton(IDR_CLOSE_BAR, IDR_CLOSE_BAR_P, + IDR_CLOSE_BAR_H, 0); + GTK_WIDGET_UNSET_FLAGS(rv->widget(), GTK_CAN_FOCUS); + GtkWidget* centering_vbox = gtk_vbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(centering_vbox), rv->widget(), TRUE, FALSE, 0); + gtk_box_pack_end(GTK_BOX(hbox), centering_vbox, FALSE, FALSE, 0); + return rv; +} + CustomContainerButton::CustomContainerButton() { GdkPixbuf* images[9]; int i = 0; diff --git a/chrome/browser/gtk/custom_button.h b/chrome/browser/gtk/custom_button.h index 2bc6cfc..518f069 100644 --- a/chrome/browser/gtk/custom_button.h +++ b/chrome/browser/gtk/custom_button.h @@ -32,6 +32,12 @@ class CustomDrawButton { GtkWidget* widget() const { return widget_.get(); } + // This is a convenience function for creating a widget that closes + // a bar (find bar, download shelf, info bars). The button will be packed in + // |hbox|. + // The caller is responsible for destroying the returned CustomDrawButton. + static CustomDrawButton* AddBarCloseButton(GtkWidget* hbox); + private: // Callback for expose, used to draw the custom graphics. static gboolean OnExpose(GtkWidget* widget, GdkEventExpose* e, diff --git a/chrome/browser/gtk/download_shelf_gtk.cc b/chrome/browser/gtk/download_shelf_gtk.cc index 18ab1bc..1d2cb2b 100644 --- a/chrome/browser/gtk/download_shelf_gtk.cc +++ b/chrome/browser/gtk/download_shelf_gtk.cc @@ -130,15 +130,10 @@ DownloadShelfGtk::DownloadShelfGtk(TabContents* tab_contents) gtk_box_pack_start(GTK_BOX(shelf_), padding_bg, FALSE, FALSE, 0); // Create and pack the close button. - close_button_.reset(new CustomDrawButton(IDR_CLOSE_BAR, - IDR_CLOSE_BAR_P, IDR_CLOSE_BAR_H, 0)); + GtkWidget* centering_vbox_; + close_button_.reset(CustomDrawButton::AddBarCloseButton(hbox_)); g_signal_connect(G_OBJECT(close_button_->widget()), "clicked", G_CALLBACK(OnButtonClick), this); - GTK_WIDGET_UNSET_FLAGS(close_button_->widget(), GTK_CAN_FOCUS); - GtkWidget* centering_vbox = gtk_vbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(centering_vbox), - close_button_->widget(), TRUE, FALSE, 0); - gtk_box_pack_end(GTK_BOX(hbox_), centering_vbox, FALSE, FALSE, 0); // Create and pack the "Show all downloads..." link. // TODO(estade): there are some pixels above and below the link that diff --git a/chrome/browser/gtk/find_bar_gtk.cc b/chrome/browser/gtk/find_bar_gtk.cc index 6ad363d..890d838 100644 --- a/chrome/browser/gtk/find_bar_gtk.cc +++ b/chrome/browser/gtk/find_bar_gtk.cc @@ -54,18 +54,11 @@ void FindBarGtk::InitWidgets() { container_.Own(gfx::CreateGtkBorderBin(hbox, &kBackgroundColor, kBarPadding, kBarPadding, kBarPadding, kBarPadding)); - close_button_.reset(new CustomDrawButton(IDR_CLOSE_BAR, IDR_CLOSE_BAR_P, - IDR_CLOSE_BAR_H, 0)); + close_button_.reset(CustomDrawButton::AddBarCloseButton(hbox)); g_signal_connect(G_OBJECT(close_button_->widget()), "clicked", G_CALLBACK(OnButtonPressed), this); gtk_widget_set_tooltip_text(close_button_->widget(), - WideToUTF8(l10n_util::GetString(IDS_FIND_IN_PAGE_CLOSE_TOOLTIP)) - .c_str()); - // Wrap the close X in a vbox to vertically align it. - GtkWidget* centering_vbox = gtk_vbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(centering_vbox), - close_button_->widget(), TRUE, FALSE, 0); - gtk_box_pack_end(GTK_BOX(hbox), centering_vbox, FALSE, FALSE, 0); + WideToUTF8(l10n_util::GetString(IDS_FIND_IN_PAGE_CLOSE_TOOLTIP)).c_str()); find_next_button_.reset(new CustomDrawButton(IDR_FINDINPAGE_NEXT, IDR_FINDINPAGE_NEXT_H, IDR_FINDINPAGE_NEXT_H, IDR_FINDINPAGE_NEXT_P)); @@ -94,7 +87,7 @@ void FindBarGtk::InitWidgets() { gtk_entry_set_has_frame(GTK_ENTRY(find_text_), FALSE); GtkWidget* border_bin = gfx::CreateGtkBorderBin(find_text_, &kBorderColor, 1, 1, 1, 0); - centering_vbox = gtk_vbox_new(FALSE, 0); + GtkWidget* centering_vbox = gtk_vbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(centering_vbox), border_bin, TRUE, FALSE, 0); gtk_box_pack_end(GTK_BOX(hbox), centering_vbox, FALSE, FALSE, 0); diff --git a/chrome/browser/gtk/infobar_container_gtk.cc b/chrome/browser/gtk/infobar_container_gtk.cc new file mode 100644 index 0000000..1b1094b --- /dev/null +++ b/chrome/browser/gtk/infobar_container_gtk.cc @@ -0,0 +1,118 @@ +// 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. + +#include "chrome/browser/gtk/infobar_container_gtk.h" + +#include <gtk/gtk.h> + +#include "base/gfx/gtk_util.h" +#include "chrome/browser/browser_window.h" +#include "chrome/browser/gtk/infobar_gtk.h" +#include "chrome/browser/tab_contents/infobar_delegate.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/common/notification_service.h" + +namespace { + +// Used by RemoveInfoBar to pass data to AnimateClosingForDelegate. +struct RemoveInfoBarData { + GtkWidget* container; + InfoBarDelegate* delegate; +}; + +void AnimateClosingForDelegate(GtkWidget* infobar_widget, + gpointer remove_info_bar_data) { + InfoBar* infobar = reinterpret_cast<InfoBar*>( + g_object_get_data(G_OBJECT(infobar_widget), "info-bar")); + RemoveInfoBarData* data = + reinterpret_cast<RemoveInfoBarData*>(remove_info_bar_data); + + if (data->delegate == infobar->delegate()) + gtk_container_remove(GTK_CONTAINER(data->container), infobar_widget); +} + +} + +// InfoBarContainerGtk, public: ------------------------------------------------ + +InfoBarContainerGtk::InfoBarContainerGtk(BrowserWindow* browser_window) + : browser_window_(browser_window), + tab_contents_(NULL), + container_(gtk_vbox_new(FALSE, 0)) { + gtk_widget_show(container_.get()); +} + +InfoBarContainerGtk::~InfoBarContainerGtk() { + browser_window_ = NULL; + ChangeTabContents(NULL); +} + +void InfoBarContainerGtk::ChangeTabContents(TabContents* contents) { + if (tab_contents_) { + NotificationService::current()->RemoveObserver( + this, NotificationType::TAB_CONTENTS_INFOBAR_ADDED, + Source<TabContents>(tab_contents_)); + NotificationService::current()->RemoveObserver( + this, NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, + Source<TabContents>(tab_contents_)); + } + + gfx::RemoveAllChildren(container_.get()); + + tab_contents_ = contents; + if (tab_contents_) { + UpdateInfoBars(); + NotificationService::current()->AddObserver( + this, NotificationType::TAB_CONTENTS_INFOBAR_ADDED, + Source<TabContents>(tab_contents_)); + NotificationService::current()->AddObserver( + this, NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, + Source<TabContents>(tab_contents_)); + } +} + +void InfoBarContainerGtk::RemoveDelegate(InfoBarDelegate* delegate) { + tab_contents_->RemoveInfoBar(delegate); +} + +// InfoBarContainerGtk, NotificationObserver implementation: ------------------- + +void InfoBarContainerGtk::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type == NotificationType::TAB_CONTENTS_INFOBAR_ADDED) { + AddInfoBar(Details<InfoBarDelegate>(details).ptr(), true); + } else if (type == NotificationType::TAB_CONTENTS_INFOBAR_REMOVED) { + RemoveInfoBar(Details<InfoBarDelegate>(details).ptr()); + } else { + NOTREACHED(); + } +} + +// InfoBarContainerGtk, private: ----------------------------------------------- + +void InfoBarContainerGtk::UpdateInfoBars() { + for (int i = 0; i < tab_contents_->infobar_delegate_count(); ++i) { + InfoBarDelegate* delegate = tab_contents_->GetInfoBarDelegateAt(i); + AddInfoBar(delegate, false); + } +} + +void InfoBarContainerGtk::AddInfoBar(InfoBarDelegate* delegate, bool animate) { + InfoBar* infobar = delegate->CreateInfoBar(); + infobar->set_container(this); + gtk_box_pack_end(GTK_BOX(container_.get()), infobar->widget(), + FALSE, FALSE, 0); + if (animate) + infobar->AnimateOpen(); + else + infobar->Open(); +} + +void InfoBarContainerGtk::RemoveInfoBar(InfoBarDelegate* delegate) { + RemoveInfoBarData remove_info_bar_data = { container_.get(), delegate }; + + gtk_container_foreach(GTK_CONTAINER(container_.get()), + AnimateClosingForDelegate, &remove_info_bar_data); +} diff --git a/chrome/browser/gtk/infobar_container_gtk.h b/chrome/browser/gtk/infobar_container_gtk.h new file mode 100644 index 0000000..60bd8d0 --- /dev/null +++ b/chrome/browser/gtk/infobar_container_gtk.h @@ -0,0 +1,68 @@ +// 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. + +#ifndef CHROME_BROWSER_GTK_INFOBAR_CONTAINER_GTK_H_ +#define CHROME_BROWSER_GTK_INFOBAR_CONTAINER_GTK_H_ + +#include "base/basictypes.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/owned_widget_gtk.h" + +class BrowserWindow; +class InfoBarDelegate; +class TabContents; + +typedef struct _GtkWidget GtkWidget; + +class InfoBarContainerGtk : public NotificationObserver { + public: + explicit InfoBarContainerGtk(BrowserWindow* browser_window); + virtual ~InfoBarContainerGtk(); + + // Get the native widget. + GtkWidget* widget() { return container_.get(); } + + // Changes the TabContents for which this container is showing InfoBars. Can + // be NULL, in which case we will simply detach ourselves from the old tab + // contents. + void ChangeTabContents(TabContents* contents); + + // Remove the specified InfoBarDelegate from the selected TabContents. This + // will notify us back and cause us to close the View. This is called from + // the InfoBar's close button handler. + void RemoveDelegate(InfoBarDelegate* delegate); + + private: + // Overridden from NotificationObserver: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + // Constructs the InfoBars needed to reflect the state of the current + // TabContents associated with this container. No animations are run during + // this process. + void UpdateInfoBars(); + + // Adds an InfoBar for the specified delegate, in response to a notification + // from the selected TabContents. + void AddInfoBar(InfoBarDelegate* delegate, bool animated); + + // Removes an InfoBar for the specified delegate, in response to a + // notification from the selected TabContents. The InfoBar's disappearance + // will be animated. + void RemoveInfoBar(InfoBarDelegate* delegate); + + // The BrowserView that hosts this InfoBarContainer. + BrowserWindow* browser_window_; + + // The TabContents for which we are currently showing InfoBars. + TabContents* tab_contents_; + + // VBox that holds the info bars. + OwnedWidgetGtk container_; + + DISALLOW_COPY_AND_ASSIGN(InfoBarContainerGtk); +}; + +#endif // CHROME_BROWSER_GTK_INFOBAR_CONTAINER_GTK_H_ diff --git a/chrome/browser/gtk/infobar_gtk.cc b/chrome/browser/gtk/infobar_gtk.cc new file mode 100644 index 0000000..a8419c6 --- /dev/null +++ b/chrome/browser/gtk/infobar_gtk.cc @@ -0,0 +1,73 @@ +// 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. + +#include "chrome/browser/gtk/infobar_gtk.h" + +#include <gtk/gtk.h> + +#include "chrome/browser/gtk/custom_button.h" +#include "chrome/browser/gtk/infobar_container_gtk.h" + +InfoBar::InfoBar(InfoBarDelegate* delegate) + : widget_(gtk_hbox_new(FALSE, 0)), + container_(NULL), + delegate_(delegate) { + g_object_set_data(G_OBJECT(widget_.get()), "info-bar", this); + close_button_.reset(CustomDrawButton::AddBarCloseButton(widget_.get())); + + // TODO(estade): remove these lines. + GtkWidget* label = gtk_label_new("Infobars not yet implemented. " + "Check back later."); + gtk_box_pack_start(GTK_BOX(widget_.get()), label, FALSE, FALSE, 10); + gtk_widget_set_size_request(widget_.get(), -1, 40); +} + +InfoBar::~InfoBar() { + widget_.Destroy(); +} + +void InfoBar::AnimateOpen() { + // TODO(port): add animations. In the meantime just Open(). + NOTIMPLEMENTED(); + Open(); +} + +void InfoBar::Open() { + gtk_widget_show_all(widget_.get()); +} + +void InfoBar::AnimateClose() { + // TODO(port): add animations. In the meantime just Close(). + NOTIMPLEMENTED(); + Close(); +} + +void InfoBar::Close() { + gtk_widget_hide(widget_.get()); +} + +void InfoBar::RemoveInfoBar() const { + container_->RemoveDelegate(delegate_); +} + +// AlertInfoBarDelegate, InfoBarDelegate overrides: ---------------------------- + +InfoBar* AlertInfoBarDelegate::CreateInfoBar() { + NOTIMPLEMENTED(); + return new InfoBar(this); +} + +// LinkInfoBarDelegate, InfoBarDelegate overrides: ----------------------------- + +InfoBar* LinkInfoBarDelegate::CreateInfoBar() { + NOTIMPLEMENTED(); + return new InfoBar(this); +} + +// ConfirmInfoBarDelegate, InfoBarDelegate overrides: -------------------------- + +InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() { + NOTIMPLEMENTED(); + return new InfoBar(this); +} diff --git a/chrome/browser/gtk/infobar_gtk.h b/chrome/browser/gtk/infobar_gtk.h new file mode 100644 index 0000000..0dff963 --- /dev/null +++ b/chrome/browser/gtk/infobar_gtk.h @@ -0,0 +1,66 @@ +// 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. + +#ifndef CHROME_BROWSER_GTK_INFOBAR_GTK_H_ +#define CHROME_BROWSER_GTK_INFOBAR_GTK_H_ + +#include "base/basictypes.h" +#include "base/scoped_ptr.h" +#include "chrome/browser/tab_contents/infobar_delegate.h" +#include "chrome/common/owned_widget_gtk.h" + +class CustomDrawButton; +class InfoBarContainerGtk; + +class InfoBar { + public: + explicit InfoBar(InfoBarDelegate* delegate); + virtual ~InfoBar(); + + InfoBarDelegate* delegate() const { return delegate_; } + + // Get the top level native GTK widget for this infobar. + GtkWidget* widget() { return widget_.get(); } + + // Set a link to the parent InfoBarContainer. This must be set before the + // InfoBar is added to the view hierarchy. + void set_container(InfoBarContainerGtk* container) { container_ = container; } + + // Starts animating the InfoBar open. + void AnimateOpen(); + + // Opens the InfoBar immediately. + void Open(); + + // Starts animating the InfoBar closed. It will not be closed until the + // animation has completed, when |Close| will be called. + void AnimateClose(); + + // Closes the InfoBar immediately and removes it from its container. Notifies + // the delegate that it has closed. The InfoBar is deleted after this function + // is called. + void Close(); + + protected: + // Removes our associated InfoBarDelegate from the associated TabContents. + // (Will lead to this InfoBar being closed). + void RemoveInfoBar() const; + + private: + // The top level GTK widget. + OwnedWidgetGtk widget_; + + // The x that closes the bar. + scoped_ptr<CustomDrawButton> close_button_; + + // The InfoBar's container + InfoBarContainerGtk* container_; + + // The InfoBar's delegate. + InfoBarDelegate* delegate_; + + DISALLOW_COPY_AND_ASSIGN(InfoBar); +}; + +#endif // CHROME_BROWSER_GTK_INFOBAR_GTK_H_ |