1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_UI_GTK_INFOBARS_INFOBAR_GTK_H_ 6 #define CHROME_BROWSER_UI_GTK_INFOBARS_INFOBAR_GTK_H_ 7 8 #include <gtk/gtk.h> 9 10 #include "base/basictypes.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "chrome/browser/infobars/infobar.h" 13 #include "chrome/browser/infobars/infobar_delegate.h" 14 #include "chrome/browser/ui/gtk/menu_gtk.h" 15 #include "content/public/browser/notification_observer.h" 16 #include "content/public/browser/notification_registrar.h" 17 #include "third_party/skia/include/core/SkColor.h" 18 #include "ui/base/gtk/gtk_signal.h" 19 #include "ui/base/gtk/owned_widget_gtk.h" 20 21 class CustomDrawButton; 22 class GtkThemeService; 23 24 namespace ui { 25 class GtkSignalRegistrar; 26 class MenuModel; 27 } 28 29 class InfoBarGtk : public InfoBar, 30 public content::NotificationObserver { 31 public: 32 // Conversion from cairo colors to SkColor. 33 typedef void (InfoBarGtk::*ColorGetter)(InfoBarDelegate::Type, 34 double* r, double* g, double* b); 35 36 InfoBarGtk(InfoBarService* owner, InfoBarDelegate* delegate); 37 virtual ~InfoBarGtk(); 38 39 // Must be called before we try to show the infobar. Inits any widgets and 40 // related objects necessary. This must be called only once during the 41 // infobar's life. 42 // 43 // NOTE: Subclasses who need to init widgets should override this function and 44 // explicitly call their parent's implementation first, then continue with 45 // further work they need to do. Failing to call the parent implementation 46 // first (or at all), or setting up widgets in the constructor instead of 47 // here, will lead to bad side effects like crashing or having this function 48 // get called repeatedly. 49 virtual void InitWidgets(); 50 51 // Get the top level native GTK widget for this infobar. 52 GtkWidget* widget() { return widget_.get(); } 53 54 GdkColor GetBorderColor() const; 55 56 // Returns the target height of the infobar if the bar is animating, 57 // otherwise 0. We care about this number since we want to prevent 58 // unnecessary renderer repaints while animating. 59 int AnimatingHeight() const; 60 61 SkColor ConvertGetColor(ColorGetter getter); 62 63 // Retrieves the component colors for the infobar's background 64 // gradient. (This varies by infobars and can be animated to change). 65 virtual void GetTopColor(InfoBarDelegate::Type type, 66 double* r, double* g, double* b); 67 virtual void GetBottomColor(InfoBarDelegate::Type type, 68 double* r, double* g, double* b); 69 70 protected: 71 // Spacing after message (and before buttons). 72 static const int kEndOfLabelSpacing; 73 74 // InfoBar: 75 virtual void PlatformSpecificShow(bool animate) OVERRIDE; 76 virtual void PlatformSpecificOnCloseSoon() OVERRIDE; 77 virtual void PlatformSpecificOnHeightsRecalculated() OVERRIDE; 78 79 // content::NotificationObserver: 80 virtual void Observe(int type, 81 const content::NotificationSource& source, 82 const content::NotificationDetails& details) OVERRIDE; 83 84 // Styles the close button as if we're doing Chrome-stlye widget rendering. 85 void ForceCloseButtonToUseChromeTheme(); 86 87 GtkWidget* hbox() { return hbox_; } 88 89 // Returns the signal registrar for this infobar. All signals representing 90 // user actions on visible widgets must go through this registrar! 91 ui::GtkSignalRegistrar* signals() { return signals_.get(); } 92 93 // Creates a label with the appropriate font and color for the current 94 // gtk-theme state. It is InfoBarGtk's responsibility to observe browser 95 // theme changes and update the label's state. 96 GtkWidget* CreateLabel(const std::string& text); 97 98 // Creates a link button with the appropriate current gtk-theme state. 99 GtkWidget* CreateLinkButton(const std::string& text); 100 101 // Builds a button with an arrow in it to emulate the menu-button style from 102 // the windows version. 103 static GtkWidget* CreateMenuButton(const std::string& text); 104 105 // Adds |display_text| to the infobar. If |link_text| is not empty, it is 106 // rendered as a hyperlink and inserted into |display_text| at |link_offset|, 107 // or right aligned in the infobar if |link_offset| is |npos|. If a link is 108 // supplied, |link_callback| must not be null. It will be invoked on click. 109 void AddLabelWithInlineLink(const string16& display_text, 110 const string16& link_text, 111 size_t link_offset, 112 GCallback callback); 113 114 // Shows the menu with |model| with the context of |sender|. 115 void ShowMenuWithModel(GtkWidget* sender, 116 MenuGtk::Delegate* delegate, 117 ui::MenuModel* model); 118 119 private: 120 void GetBackgroundColor(SkColor color, double* r, double* g, double* b); 121 void UpdateBorderColor(); 122 123 CHROMEGTK_CALLBACK_0(InfoBarGtk, void, OnCloseButton); 124 CHROMEGTK_CALLBACK_1(InfoBarGtk, gboolean, OnBackgroundExpose, 125 GdkEventExpose*); 126 CHROMEGTK_CALLBACK_2(InfoBarGtk, void, OnChildSizeRequest, GtkWidget*, 127 GtkRequisition*); 128 129 // A GtkExpandedContainer that contains |bg_box_| so we can vary the height of 130 // the infobar. 131 ui::OwnedWidgetGtk widget_; 132 133 // The second highest widget in the hierarchy (after the |widget_|). 134 GtkWidget* bg_box_; 135 136 // The hbox that holds infobar elements (button, text, icon, etc.). 137 GtkWidget* hbox_; 138 139 // The x that closes the bar. 140 scoped_ptr<CustomDrawButton> close_button_; 141 142 // The theme provider, used for getting border colors. 143 GtkThemeService* theme_service_; 144 145 content::NotificationRegistrar registrar_; 146 147 // A list of signals which we clear out once we're closing. 148 scoped_ptr<ui::GtkSignalRegistrar> signals_; 149 150 // The current menu displayed. Can be null. We own this on the base class so 151 // we can cancel the menu while we're closing. 152 scoped_ptr<MenuGtk> menu_; 153 154 DISALLOW_COPY_AND_ASSIGN(InfoBarGtk); 155 }; 156 157 #endif // CHROME_BROWSER_UI_GTK_INFOBARS_INFOBAR_GTK_H_ 158