Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(215)

Side by Side Diff: chrome/browser/ui/gtk/infobars/infobar_gtk.cc

Issue 231733005: Delete the GTK+ port of Chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remerge to ToT Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 #include "chrome/browser/ui/gtk/infobars/infobar_gtk.h"
6
7 #include "base/debug/trace_event.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/themes/theme_properties.h"
12 #include "chrome/browser/ui/gtk/browser_window_gtk.h"
13 #include "chrome/browser/ui/gtk/custom_button.h"
14 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h"
15 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
16 #include "chrome/browser/ui/gtk/gtk_util.h"
17 #include "chrome/browser/ui/gtk/infobars/infobar_container_gtk.h"
18 #include "content/public/browser/notification_source.h"
19 #include "content/public/browser/web_contents.h"
20 #include "ui/base/gtk/gtk_expanded_container.h"
21 #include "ui/base/gtk/gtk_hig_constants.h"
22 #include "ui/base/gtk/gtk_signal_registrar.h"
23 #include "ui/base/models/menu_model.h"
24 #include "ui/gfx/gtk_util.h"
25 #include "ui/gfx/image/image.h"
26
27 namespace {
28
29 // Pixels between infobar elements.
30 const int kElementPadding = 5;
31
32 // Extra padding on either end of info bar.
33 const int kLeftPadding = 5;
34 const int kRightPadding = 5;
35
36 } // namespace
37
38
39 // InfoBar --------------------------------------------------------------------
40
41 // static
42 const int InfoBar::kSeparatorLineHeight = 1;
43 const int InfoBar::kDefaultArrowTargetHeight = 9;
44 const int InfoBar::kMaximumArrowTargetHeight = 24;
45 const int InfoBar::kDefaultArrowTargetHalfWidth = kDefaultArrowTargetHeight;
46 const int InfoBar::kMaximumArrowTargetHalfWidth = 14;
47 const int InfoBar::kDefaultBarTargetHeight = 36;
48
49
50 // InfoBarGtk -----------------------------------------------------------------
51
52 // static
53 const int InfoBarGtk::kEndOfLabelSpacing = 6;
54
55 InfoBarGtk::InfoBarGtk(scoped_ptr<InfoBarDelegate> delegate)
56 : InfoBar(delegate.Pass()),
57 bg_box_(NULL),
58 hbox_(NULL),
59 theme_service_(NULL),
60 signals_(new ui::GtkSignalRegistrar) {
61 }
62
63 InfoBarGtk::~InfoBarGtk() {
64 }
65
66 GdkColor InfoBarGtk::GetBorderColor() const {
67 DCHECK(theme_service_);
68 return theme_service_->GetBorderColor();
69 }
70
71 int InfoBarGtk::AnimatingHeight() const {
72 return animation().is_animating() ? bar_target_height() : 0;
73 }
74
75 SkColor InfoBarGtk::ConvertGetColor(ColorGetter getter) {
76 double r, g, b;
77 (this->*getter)(delegate()->GetInfoBarType(), &r, &g, &b);
78 return SkColorSetARGB(255, 255 * r, 255 * g, 255 * b);
79 }
80
81 void InfoBarGtk::GetTopColor(InfoBarDelegate::Type type,
82 double* r, double* g, double* b) {
83 GetBackgroundColor(InfoBar::GetTopColor(type), r, g, b);
84 }
85
86 void InfoBarGtk::GetBottomColor(InfoBarDelegate::Type type,
87 double* r, double* g, double* b) {
88 GetBackgroundColor(InfoBar::GetBottomColor(type), r, g, b);
89 }
90
91 void InfoBarGtk::PlatformSpecificSetOwner() {
92 DCHECK(owner());
93 DCHECK(!theme_service_);
94 theme_service_ = GtkThemeService::GetFrom(Profile::FromBrowserContext(
95 owner()->web_contents()->GetBrowserContext()));
96
97 // Create |hbox_| and pad the sides.
98 hbox_ = gtk_hbox_new(FALSE, kElementPadding);
99
100 // Make the whole infor bar horizontally shrinkable.
101 gtk_widget_set_size_request(hbox_, 0, -1);
102
103 GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1);
104 gtk_alignment_set_padding(GTK_ALIGNMENT(padding),
105 0, 0, kLeftPadding, kRightPadding);
106
107 bg_box_ = gtk_event_box_new();
108 gtk_widget_set_app_paintable(bg_box_, TRUE);
109 g_signal_connect(bg_box_, "expose-event",
110 G_CALLBACK(OnBackgroundExposeThunk), this);
111 gtk_container_add(GTK_CONTAINER(padding), hbox_);
112 gtk_container_add(GTK_CONTAINER(bg_box_), padding);
113
114 // Add the icon on the left, if any.
115 gfx::Image icon = delegate()->GetIcon();
116 if (!icon.IsEmpty()) {
117 GtkWidget* image = gtk_image_new_from_pixbuf(icon.ToGdkPixbuf());
118
119 gtk_misc_set_alignment(GTK_MISC(image), 0.5, 0.5);
120
121 gtk_box_pack_start(GTK_BOX(hbox_), image, FALSE, FALSE, 0);
122 }
123
124 close_button_.reset(CustomDrawButton::CloseButtonBar(theme_service_));
125 gtk_util::CenterWidgetInHBox(hbox_, close_button_->widget(), true, 0);
126 signals_->Connect(close_button_->widget(), "clicked",
127 G_CALLBACK(OnCloseButtonThunk), this);
128
129 widget_.Own(gtk_expanded_container_new());
130 gtk_container_add(GTK_CONTAINER(widget_.get()), bg_box_);
131 gtk_widget_set_size_request(widget_.get(), -1, 0);
132
133 g_signal_connect(widget_.get(), "child-size-request",
134 G_CALLBACK(OnChildSizeRequestThunk),
135 this);
136
137 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
138 content::Source<ThemeService>(theme_service_));
139 UpdateBorderColor();
140 }
141
142 void InfoBarGtk::PlatformSpecificShow(bool animate) {
143 DCHECK(bg_box_);
144
145 DCHECK(widget());
146 gtk_widget_show_all(widget());
147 gtk_widget_set_size_request(widget(), -1, bar_height());
148
149 GdkWindow* gdk_window = gtk_widget_get_window(bg_box_);
150 if (gdk_window)
151 gdk_window_lower(gdk_window);
152 }
153
154 void InfoBarGtk::PlatformSpecificOnCloseSoon() {
155 // We must close all menus and prevent any signals from being emitted while
156 // we are animating the info bar closed.
157 menu_.reset();
158 signals_.reset();
159 }
160
161 void InfoBarGtk::PlatformSpecificOnHeightsRecalculated() {
162 DCHECK(bg_box_);
163 DCHECK(widget());
164 gtk_widget_set_size_request(bg_box_, -1, bar_target_height());
165 gtk_expanded_container_move(GTK_EXPANDED_CONTAINER(widget()),
166 bg_box_, 0,
167 bar_height() - bar_target_height());
168
169 gtk_widget_set_size_request(widget(), -1, bar_height());
170 gtk_widget_queue_draw(widget());
171 }
172
173 void InfoBarGtk::Observe(int type,
174 const content::NotificationSource& source,
175 const content::NotificationDetails& details) {
176 DCHECK(widget());
177 UpdateBorderColor();
178 }
179
180 void InfoBarGtk::ForceCloseButtonToUseChromeTheme() {
181 close_button_->ForceChromeTheme();
182 }
183
184 GtkWidget* InfoBarGtk::CreateLabel(const std::string& text) {
185 DCHECK(theme_service_);
186 return theme_service_->BuildLabel(text, ui::kGdkBlack);
187 }
188
189 GtkWidget* InfoBarGtk::CreateLinkButton(const std::string& text) {
190 DCHECK(theme_service_);
191 return theme_service_->BuildChromeLinkButton(text);
192 }
193
194 // static
195 GtkWidget* InfoBarGtk::CreateMenuButton(const std::string& text) {
196 GtkWidget* button = gtk_button_new();
197 GtkWidget* former_child = gtk_bin_get_child(GTK_BIN(button));
198 if (former_child)
199 gtk_container_remove(GTK_CONTAINER(button), former_child);
200
201 GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
202
203 GtkWidget* label = gtk_label_new(text.c_str());
204 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
205
206 GtkWidget* arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE);
207 gtk_box_pack_start(GTK_BOX(hbox), arrow, FALSE, FALSE, 0);
208
209 gtk_container_add(GTK_CONTAINER(button), hbox);
210
211 return button;
212 }
213
214 void InfoBarGtk::AddLabelWithInlineLink(const base::string16& display_text,
215 const base::string16& link_text,
216 size_t link_offset,
217 GCallback callback) {
218 DCHECK(hbox_);
219 GtkWidget* link_button = CreateLinkButton(base::UTF16ToUTF8(link_text));
220 gtk_util::ForceFontSizePixels(
221 GTK_CHROME_LINK_BUTTON(link_button)->label, 13.4);
222 DCHECK(callback);
223 signals_->Connect(link_button, "clicked", callback, this);
224 gtk_util::SetButtonTriggersNavigation(link_button);
225
226 GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
227 // We want the link to be horizontally shrinkable, so that the Chrome
228 // window can be resized freely even with a very long link.
229 gtk_widget_set_size_request(hbox, 0, -1);
230 gtk_box_pack_start(GTK_BOX(hbox_), hbox, TRUE, TRUE, 0);
231
232 // Need to insert the link inside the display text.
233 GtkWidget* initial_label = CreateLabel(
234 base::UTF16ToUTF8(display_text.substr(0, link_offset)));
235 GtkWidget* trailing_label = CreateLabel(
236 base::UTF16ToUTF8(display_text.substr(link_offset)));
237
238 gtk_util::ForceFontSizePixels(initial_label, 13.4);
239 gtk_util::ForceFontSizePixels(trailing_label, 13.4);
240
241 // TODO(joth): None of the label widgets are set as shrinkable here, meaning
242 // the text will run under the close button etc. when the width is restricted,
243 // rather than eliding.
244
245 // We don't want any spacing between the elements, so we pack them into
246 // this hbox that doesn't use kElementPadding.
247 gtk_box_pack_start(GTK_BOX(hbox), initial_label, FALSE, FALSE, 0);
248 gtk_util::CenterWidgetInHBox(hbox, link_button, false, 0);
249 gtk_box_pack_start(GTK_BOX(hbox), trailing_label, FALSE, FALSE, 0);
250 }
251
252 void InfoBarGtk::ShowMenuWithModel(GtkWidget* sender,
253 MenuGtk::Delegate* delegate,
254 ui::MenuModel* model) {
255 menu_.reset(new MenuGtk(delegate, model));
256 menu_->PopupForWidget(sender, 1, gtk_get_current_event_time());
257 }
258
259 void InfoBarGtk::GetBackgroundColor(SkColor color,
260 double* r, double* g, double* b) {
261 DCHECK(theme_service_);
262 if (theme_service_->UsingNativeTheme())
263 color = theme_service_->GetColor(ThemeProperties::COLOR_TOOLBAR);
264 *r = SkColorGetR(color) / 255.0;
265 *g = SkColorGetG(color) / 255.0;
266 *b = SkColorGetB(color) / 255.0;
267 }
268
269 void InfoBarGtk::UpdateBorderColor() {
270 DCHECK(widget());
271 gtk_widget_queue_draw(widget());
272 }
273
274 void InfoBarGtk::OnCloseButton(GtkWidget* button) {
275 // If we're not owned, we're already closing, so don't call
276 // InfoBarDismissed(), since this can lead to us double-recording dismissals.
277 if (owner())
278 delegate()->InfoBarDismissed();
279 RemoveSelf();
280 }
281
282 gboolean InfoBarGtk::OnBackgroundExpose(GtkWidget* sender,
283 GdkEventExpose* event) {
284 TRACE_EVENT0("ui::gtk", "InfoBarGtk::OnBackgroundExpose");
285 DCHECK(theme_service_);
286
287 GtkAllocation allocation;
288 gtk_widget_get_allocation(sender, &allocation);
289 const int height = allocation.height;
290
291 cairo_t* cr = gdk_cairo_create(gtk_widget_get_window(sender));
292 gdk_cairo_rectangle(cr, &event->area);
293 cairo_clip(cr);
294
295 cairo_pattern_t* pattern = cairo_pattern_create_linear(0, 0, 0, height);
296
297 double top_r, top_g, top_b;
298 GetTopColor(delegate()->GetInfoBarType(), &top_r, &top_g, &top_b);
299 cairo_pattern_add_color_stop_rgb(pattern, 0.0, top_r, top_g, top_b);
300
301 double bottom_r, bottom_g, bottom_b;
302 GetBottomColor(delegate()->GetInfoBarType(), &bottom_r, &bottom_g, &bottom_b);
303 cairo_pattern_add_color_stop_rgb(
304 pattern, 1.0, bottom_r, bottom_g, bottom_b);
305 cairo_set_source(cr, pattern);
306 cairo_paint(cr);
307 cairo_pattern_destroy(pattern);
308
309 // Draw the bottom border.
310 GdkColor border_color = GetBorderColor();
311 cairo_set_source_rgb(cr, border_color.red / 65535.0,
312 border_color.green / 65535.0,
313 border_color.blue / 65535.0);
314 cairo_set_line_width(cr, 1.0);
315 cairo_move_to(cr, 0, allocation.height - 0.5);
316 cairo_rel_line_to(cr, allocation.width, 0);
317 cairo_stroke(cr);
318
319 cairo_destroy(cr);
320
321 if (container()) {
322 static_cast<InfoBarContainerGtk*>(container())->
323 PaintInfobarBitsOn(sender, event, this);
324 }
325
326 return FALSE;
327 }
328
329 void InfoBarGtk::OnChildSizeRequest(GtkWidget* expanded,
330 GtkWidget* child,
331 GtkRequisition* requisition) {
332 requisition->height = -1;
333 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698