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

Side by Side Diff: chrome/browser/ui/panels/panel_browser_titlebar_gtk.cc

Issue 10908153: [Panel refactor] Deprecate old panels. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix linux_chromeos test failure Created 8 years, 3 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/panels/panel_browser_titlebar_gtk.h"
6
7 #include "base/utf_string_conversions.h"
8 #include "chrome/browser/ui/browser.h"
9 #include "chrome/browser/ui/gtk/custom_button.h"
10 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
11 #include "chrome/browser/ui/gtk/gtk_util.h"
12 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
13 #include "chrome/browser/ui/panels/panel.h"
14 #include "chrome/browser/ui/panels/panel_browser_window_gtk.h"
15 #include "chrome/common/chrome_notification_types.h"
16 #include "content/public/browser/notification_service.h"
17 #include "content/public/browser/web_contents.h"
18 #include "grit/generated_resources.h"
19 #include "grit/theme_resources.h"
20 #include "ui/base/gtk/gtk_compat.h"
21 #include "ui/base/l10n/l10n_util.h"
22 #include "ui/base/resource/resource_bundle.h"
23 #include "ui/gfx/image/image.h"
24 #include "ui/gfx/skia_utils_gtk.h"
25
26 namespace {
27
28 // Padding around the titlebar.
29 const int kPanelTitlebarPaddingTop = 7;
30 const int kPanelTitlebarPaddingBottom = 7;
31 const int kPanelTitlebarPaddingLeft = 4;
32 const int kPanelTitlebarPaddingRight = 8;
33
34 // Spacing between buttons of panel's titlebar.
35 const int kPanelButtonSpacing = 5;
36
37 // Spacing between the icon and the title text.
38 const int kPanelIconTitleSpacing = 9;
39
40 // Color used to draw title text under default theme.
41 const SkColor kTitleTextDefaultColor = SkColorSetRGB(0xf9, 0xf9, 0xf9);
42
43 // Markup used to paint the title with the desired font.
44 const char* const kTitleMarkupPrefix = "<span face='Arial' size='11264'>";
45 const char* const kTitleMarkupSuffix = "</span>";
46
47 } // namespace
48
49 PanelBrowserTitlebarGtk::PanelBrowserTitlebarGtk(
50 PanelBrowserWindowGtk* browser_window, GtkWindow* window)
51 : browser_window_(browser_window),
52 window_(window),
53 container_(NULL),
54 titlebar_right_buttons_vbox_(NULL),
55 titlebar_right_buttons_hbox_(NULL),
56 icon_(NULL),
57 title_(NULL),
58 theme_service_(NULL) {
59 }
60
61 PanelBrowserTitlebarGtk::~PanelBrowserTitlebarGtk() {
62 }
63
64 void PanelBrowserTitlebarGtk::Init() {
65 container_ = gtk_event_box_new();
66 gtk_widget_set_name(container_, "chrome-panel-titlebar");
67 gtk_event_box_set_visible_window(GTK_EVENT_BOX(container_), FALSE);
68
69 // We use an alignment to control the titlebar paddings.
70 GtkWidget* container_alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
71 gtk_container_add(GTK_CONTAINER(container_), container_alignment);
72 gtk_alignment_set_padding(GTK_ALIGNMENT(container_alignment),
73 kPanelTitlebarPaddingTop,
74 kPanelTitlebarPaddingBottom,
75 kPanelTitlebarPaddingLeft,
76 kPanelTitlebarPaddingRight);
77
78 // Add a container box.
79 GtkWidget* container_hbox = gtk_hbox_new(FALSE, 0);
80 gtk_container_add(GTK_CONTAINER(container_alignment), container_hbox);
81
82 g_signal_connect(window_, "window-state-event",
83 G_CALLBACK(OnWindowStateChangedThunk), this);
84
85 // Add minimize/restore and close buttons. Panel buttons are always placed
86 // on the right part of the titlebar.
87 titlebar_right_buttons_vbox_ = gtk_vbox_new(FALSE, 0);
88 gtk_box_pack_end(GTK_BOX(container_hbox), titlebar_right_buttons_vbox_,
89 FALSE, FALSE, 0);
90 BuildButtons();
91
92 // Add hbox for holding icon and title.
93 GtkWidget* icon_title_hbox = gtk_hbox_new(FALSE, kPanelIconTitleSpacing);
94 gtk_box_pack_start(GTK_BOX(container_hbox), icon_title_hbox, TRUE, TRUE, 0);
95
96 // Add icon. We use the app logo as a placeholder image so the title doesn't
97 // jump around.
98 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
99 icon_ = gtk_image_new_from_pixbuf(rb.GetNativeImageNamed(
100 IDR_PRODUCT_LOGO_16, ui::ResourceBundle::RTL_ENABLED).ToGdkPixbuf());
101 g_object_set_data(G_OBJECT(icon_), "left-align-popup",
102 reinterpret_cast<void*>(true));
103 gtk_box_pack_start(GTK_BOX(icon_title_hbox), icon_, FALSE, FALSE, 0);
104
105 // Add title.
106 title_ = gtk_label_new(NULL);
107 gtk_label_set_ellipsize(GTK_LABEL(title_), PANGO_ELLIPSIZE_END);
108 gtk_misc_set_alignment(GTK_MISC(title_), 0.0, 0.5);
109 gtk_box_pack_start(GTK_BOX(icon_title_hbox), title_, TRUE, TRUE, 0);
110
111 UpdateTitleAndIcon();
112
113 theme_service_ = GtkThemeService::GetFrom(
114 browser_window_->panel()->profile());
115 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
116 content::Source<ThemeService>(theme_service_));
117 theme_service_->InitThemesFor(this);
118
119 gtk_widget_show_all(container_);
120 }
121
122 SkColor PanelBrowserTitlebarGtk::GetTextColor() const {
123 if (browser_window_->UsingDefaultTheme())
124 return kTitleTextDefaultColor;
125 return theme_service_->GetColor(browser_window_->paint_state() ==
126 PanelBrowserWindowGtk::PAINT_AS_ACTIVE ?
127 ThemeService::COLOR_TAB_TEXT :
128 ThemeService::COLOR_BACKGROUND_TAB_TEXT);
129 }
130
131 void PanelBrowserTitlebarGtk::BuildButtons() {
132 minimize_button_.reset(CreateButton(panel::MINIMIZE_BUTTON));
133 restore_button_.reset(CreateButton(panel::RESTORE_BUTTON));
134 close_button_.reset(CreateButton(panel::CLOSE_BUTTON));
135
136 // We control visibility of minimize and restore buttons.
137 gtk_widget_set_no_show_all(minimize_button_->widget(), TRUE);
138 gtk_widget_set_no_show_all(restore_button_->widget(), TRUE);
139
140 // Now show the correct widgets in the two hierarchies.
141 UpdateMinimizeRestoreButtonVisibility();
142 }
143
144 CustomDrawButton* PanelBrowserTitlebarGtk::CreateButton(
145 panel::TitlebarButtonType button_type) {
146 int normal_image_id = -1;
147 int pressed_image_id = -1;
148 int hover_image_id = -1;
149 int tooltip_id = -1;
150 GetButtonResources(button_type, &normal_image_id, &pressed_image_id,
151 &hover_image_id, &tooltip_id);
152
153 CustomDrawButton* button = new CustomDrawButton(normal_image_id,
154 pressed_image_id,
155 hover_image_id,
156 0);
157 gtk_widget_add_events(GTK_WIDGET(button->widget()), GDK_POINTER_MOTION_MASK);
158 g_signal_connect(button->widget(), "clicked",
159 G_CALLBACK(OnButtonClickedThunk), this);
160
161 std::string localized_tooltip = l10n_util::GetStringUTF8(tooltip_id);
162 gtk_widget_set_tooltip_text(button->widget(),
163 localized_tooltip.c_str());
164
165 GtkWidget* box = GetButtonHBox();
166 gtk_box_pack_start(GTK_BOX(box), button->widget(), FALSE, FALSE, 0);
167 return button;
168 }
169
170 void PanelBrowserTitlebarGtk::GetButtonResources(
171 panel::TitlebarButtonType button_type,
172 int* normal_image_id,
173 int* pressed_image_id,
174 int* hover_image_id,
175 int* tooltip_id) const {
176 switch (button_type) {
177 case panel::CLOSE_BUTTON:
178 *normal_image_id = IDR_PANEL_CLOSE;
179 *pressed_image_id = IDR_PANEL_CLOSE_C;
180 *hover_image_id = IDR_PANEL_CLOSE_H;
181 *tooltip_id = IDS_PANEL_CLOSE_TOOLTIP;
182 break;
183 case panel::MINIMIZE_BUTTON:
184 *normal_image_id = IDR_PANEL_MINIMIZE;
185 *pressed_image_id = IDR_PANEL_MINIMIZE_C;
186 *hover_image_id = IDR_PANEL_MINIMIZE_H;
187 *tooltip_id = IDS_PANEL_MINIMIZE_TOOLTIP;
188 break;
189 case panel::RESTORE_BUTTON:
190 *normal_image_id = IDR_PANEL_RESTORE;
191 *pressed_image_id = IDR_PANEL_RESTORE_C;
192 *hover_image_id = IDR_PANEL_RESTORE_H;
193 *tooltip_id = IDS_PANEL_RESTORE_TOOLTIP;
194 break;
195 }
196 }
197
198 GtkWidget* PanelBrowserTitlebarGtk::GetButtonHBox() {
199 if (!titlebar_right_buttons_hbox_) {
200 // We put the minimize/restore/close buttons in a vbox so they are top
201 // aligned (up to padding) and don't vertically stretch.
202 titlebar_right_buttons_hbox_ = gtk_hbox_new(FALSE, kPanelButtonSpacing);
203 gtk_box_pack_start(GTK_BOX(titlebar_right_buttons_vbox_),
204 titlebar_right_buttons_hbox_, FALSE, FALSE, 0);
205 }
206
207 return titlebar_right_buttons_hbox_;
208 }
209
210 void PanelBrowserTitlebarGtk::UpdateCustomFrame(bool use_custom_frame) {
211 // Nothing to do.
212 }
213
214 void PanelBrowserTitlebarGtk::UpdateTitleAndIcon() {
215 std::string title_text =
216 UTF16ToUTF8(browser_window_->panel()->GetWindowTitle());
217
218 // Add the markup to show the title in the desired font.
219 gchar* escaped_title_text = g_markup_escape_text(title_text.c_str(), -1);
220 gchar* title_text_with_markup = g_strconcat(kTitleMarkupPrefix,
221 escaped_title_text,
222 kTitleMarkupSuffix,
223 NULL);
224 gtk_label_set_markup(GTK_LABEL(title_), title_text_with_markup);
225 g_free(escaped_title_text);
226 g_free(title_text_with_markup);
227 }
228
229 void PanelBrowserTitlebarGtk::UpdateThrobber(
230 content::WebContents* web_contents) {
231 if (web_contents && web_contents->IsLoading()) {
232 GdkPixbuf* icon_pixbuf =
233 throbber_.GetNextFrame(web_contents->IsWaitingForResponse());
234 gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), icon_pixbuf);
235 } else {
236 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
237
238 gfx::Image icon = browser_window_->panel()->GetCurrentPageIcon();
239 if (icon.IsEmpty()) {
240 // Fallback to the Chromium icon if the page has no icon.
241 gtk_image_set_from_pixbuf(GTK_IMAGE(icon_),
242 rb.GetNativeImageNamed(IDR_PRODUCT_LOGO_16).ToGdkPixbuf());
243 } else {
244 GdkPixbuf* icon_pixbuf = icon.ToGdkPixbuf();
245 gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), icon_pixbuf);
246 }
247
248 throbber_.Reset();
249 }
250 }
251
252 void PanelBrowserTitlebarGtk::ShowContextMenu(GdkEventButton* event) {
253 // Panel does not show any context menu.
254 }
255
256 void PanelBrowserTitlebarGtk::UpdateTextColor() {
257 GdkColor text_color = gfx::SkColorToGdkColor(GetTextColor());
258 gtk_util::SetLabelColor(title_, &text_color);
259 }
260
261 void PanelBrowserTitlebarGtk::UpdateMinimizeRestoreButtonVisibility() {
262 Panel* panel = browser_window_->panel();
263 gtk_widget_set_visible(minimize_button_->widget(), panel->CanMinimize());
264 gtk_widget_set_visible(restore_button_->widget(), panel->CanRestore());
265 }
266
267 gboolean PanelBrowserTitlebarGtk::OnWindowStateChanged(
268 GtkWindow* window, GdkEventWindowState* event) {
269 UpdateTextColor();
270 return FALSE;
271 }
272
273 void PanelBrowserTitlebarGtk::OnButtonClicked(GtkWidget* button) {
274 if (close_button_->widget() == button) {
275 browser_window_->panel()->Close();
276 return;
277 }
278
279 GdkEvent* event = gtk_get_current_event();
280 DCHECK(event && event->type == GDK_BUTTON_RELEASE);
281
282 if (minimize_button_->widget() == button) {
283 browser_window_->panel()->OnMinimizeButtonClicked(
284 (event->button.state & GDK_CONTROL_MASK) ?
285 panel::APPLY_TO_ALL : panel::NO_MODIFIER);
286 } else if (restore_button_->widget() == button) {
287 browser_window_->panel()->OnRestoreButtonClicked(
288 (event->button.state & GDK_CONTROL_MASK) ?
289 panel::APPLY_TO_ALL : panel::NO_MODIFIER);
290 }
291
292 gdk_event_free(event);
293 }
294
295 void PanelBrowserTitlebarGtk::Observe(
296 int type,
297 const content::NotificationSource& source,
298 const content::NotificationDetails& details) {
299 switch (type) {
300 case chrome::NOTIFICATION_BROWSER_THEME_CHANGED:
301 UpdateTextColor();
302 break;
303 default:
304 NOTREACHED();
305 }
306 }
307
308 void PanelBrowserTitlebarGtk::SendEnterNotifyToCloseButtonIfUnderMouse() {
309 if (!close_button())
310 return;
311
312 gint x;
313 gint y;
314 GtkAllocation widget_allocation = close_button()->WidgetAllocation();
315 gtk_widget_get_pointer(GTK_WIDGET(close_button()->widget()), &x, &y);
316
317 gfx::Rect button_rect(0, 0, widget_allocation.width,
318 widget_allocation.height);
319 if (!button_rect.Contains(x, y)) {
320 // Mouse is not over the close button.
321 return;
322 }
323
324 // Create and emit an enter-notify-event on close button.
325 GValue return_value;
326 return_value.g_type = G_TYPE_BOOLEAN;
327 g_value_set_boolean(&return_value, false);
328
329 GdkEvent* event = gdk_event_new(GDK_ENTER_NOTIFY);
330 event->crossing.window =
331 gtk_button_get_event_window(GTK_BUTTON(close_button()->widget()));
332 event->crossing.send_event = FALSE;
333 event->crossing.subwindow = gtk_widget_get_window(close_button()->widget());
334 event->crossing.time = gtk_util::XTimeNow();
335 event->crossing.x = x;
336 event->crossing.y = y;
337 event->crossing.x_root = widget_allocation.x;
338 event->crossing.y_root = widget_allocation.y;
339 event->crossing.mode = GDK_CROSSING_NORMAL;
340 event->crossing.detail = GDK_NOTIFY_ANCESTOR;
341 event->crossing.focus = true;
342 event->crossing.state = 0;
343
344 g_signal_emit_by_name(GTK_OBJECT(close_button()->widget()),
345 "enter-notify-event", event,
346 &return_value);
347 }
348
349 GtkWidget* PanelBrowserTitlebarGtk::widget() const {
350 return container_;
351 }
352
353 void PanelBrowserTitlebarGtk::set_window(GtkWindow* window) {
354 window_ = window;
355 }
356
357 AvatarMenuButtonGtk* PanelBrowserTitlebarGtk::avatar_button() const {
358 // Not supported in panel.
359 return NULL;
360 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/panels/panel_browser_titlebar_gtk.h ('k') | chrome/browser/ui/panels/panel_browser_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698