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

Side by Side Diff: chrome/browser/ui/gtk/panels/panel_titlebar_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/panels/panel_titlebar_gtk.h"
6
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/themes/theme_properties.h"
9 #include "chrome/browser/ui/gtk/custom_button.h"
10 #include "chrome/browser/ui/gtk/gtk_util.h"
11 #include "chrome/browser/ui/gtk/panels/panel_gtk.h"
12 #include "chrome/browser/ui/panels/panel.h"
13 #include "content/public/browser/web_contents.h"
14 #include "grit/generated_resources.h"
15 #include "grit/theme_resources.h"
16 #include "ui/base/l10n/l10n_util.h"
17 #include "ui/base/resource/resource_bundle.h"
18 #include "ui/gfx/gtk_compat.h"
19 #include "ui/gfx/image/image.h"
20 #include "ui/gfx/skia_utils_gtk.h"
21
22 namespace {
23
24 // Padding around the titlebar.
25 const int kPanelTitlebarPaddingTop = 4;
26 const int kPanelTitlebarPaddingBottom = 8;
27 const int kPanelTitlebarPaddingLeft = 6;
28 const int kPanelTitlebarPaddingRight = 0;
29
30 // Padding around the box containing icon and title.
31 const int kPanelIconTitlePaddingTop = 3;
32 const int kPanelIconTitlePaddingBottom = 0;
33 const int kPanelIconTitlePaddingLeft = 0;
34 const int kPanelIconTitlePaddingRight = 0;
35
36 // Spacing between buttons of panel's titlebar.
37 const int kPanelButtonSpacing = 5;
38
39 // Spacing between the icon and the title text.
40 const int kPanelIconTitleSpacing = 9;
41
42 // Color used to draw title text under default theme.
43 const SkColor kTitleTextDefaultColor = SkColorSetRGB(0xf9, 0xf9, 0xf9);
44
45 // Markup used to paint the title with the desired font.
46 const char* const kTitleMarkupPrefix =
47 "<span face='Arial' weight='bold' size='11264'>";
48 const char* const kTitleMarkupSuffix = "</span>";
49
50 } // namespace
51
52 PanelTitlebarGtk::PanelTitlebarGtk(PanelGtk* panel_gtk)
53 : panel_gtk_(panel_gtk),
54 container_(NULL),
55 titlebar_right_buttons_vbox_(NULL),
56 titlebar_right_buttons_hbox_(NULL),
57 icon_(NULL),
58 title_(NULL) {
59 }
60
61 PanelTitlebarGtk::~PanelTitlebarGtk() {
62 }
63
64 void PanelTitlebarGtk::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 // Add minimize/restore and close buttons. Panel buttons are always placed
83 // on the right part of the titlebar.
84 titlebar_right_buttons_vbox_ = gtk_vbox_new(FALSE, 0);
85 gtk_box_pack_end(GTK_BOX(container_hbox), titlebar_right_buttons_vbox_,
86 FALSE, FALSE, 0);
87 BuildButtons();
88
89 // Add an extra alignment to control the paddings for icon and title.
90 GtkWidget* icon_title_alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
91 gtk_container_add(GTK_CONTAINER(container_hbox), icon_title_alignment);
92 gtk_alignment_set_padding(GTK_ALIGNMENT(icon_title_alignment),
93 kPanelIconTitlePaddingTop,
94 kPanelIconTitlePaddingBottom,
95 kPanelIconTitlePaddingLeft,
96 kPanelIconTitlePaddingRight);
97
98 // Add hbox for holding icon and title.
99 GtkWidget* icon_title_hbox = gtk_hbox_new(FALSE, kPanelIconTitleSpacing);
100 gtk_container_add(GTK_CONTAINER(icon_title_alignment), icon_title_hbox);
101
102 // Add icon. We use the app logo as a placeholder image so the title doesn't
103 // jump around.
104 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
105 icon_ = gtk_image_new_from_pixbuf(rb.GetNativeImageNamed(
106 IDR_PRODUCT_LOGO_16, ui::ResourceBundle::RTL_ENABLED).ToGdkPixbuf());
107 g_object_set_data(G_OBJECT(icon_), "left-align-popup",
108 reinterpret_cast<void*>(true));
109 gtk_box_pack_start(GTK_BOX(icon_title_hbox), icon_, FALSE, FALSE, 0);
110
111 // Add title.
112 title_ = gtk_label_new(NULL);
113 gtk_label_set_ellipsize(GTK_LABEL(title_), PANGO_ELLIPSIZE_END);
114 gtk_misc_set_alignment(GTK_MISC(title_), 0.0, 0.5);
115 gtk_box_pack_start(GTK_BOX(icon_title_hbox), title_, TRUE, TRUE, 0);
116 UpdateTitleAndIcon();
117 UpdateTextColor();
118
119 gtk_widget_show_all(container_);
120 }
121
122 SkColor PanelTitlebarGtk::GetTextColor() const {
123 return kTitleTextDefaultColor;
124 }
125
126 void PanelTitlebarGtk::BuildButtons() {
127 minimize_button_.reset(CreateButton(panel::MINIMIZE_BUTTON));
128 restore_button_.reset(CreateButton(panel::RESTORE_BUTTON));
129 close_button_.reset(CreateButton(panel::CLOSE_BUTTON));
130
131 // We control visibility of minimize and restore buttons.
132 gtk_widget_set_no_show_all(minimize_button_->widget(), TRUE);
133 gtk_widget_set_no_show_all(restore_button_->widget(), TRUE);
134
135 // Now show the correct widgets in the two hierarchies.
136 UpdateMinimizeRestoreButtonVisibility();
137 }
138
139 CustomDrawButton* PanelTitlebarGtk::CreateButton(
140 panel::TitlebarButtonType button_type) {
141 int normal_image_id = -1;
142 int pressed_image_id = -1;
143 int hover_image_id = -1;
144 int tooltip_id = -1;
145 GetButtonResources(button_type, &normal_image_id, &pressed_image_id,
146 &hover_image_id, &tooltip_id);
147
148 CustomDrawButton* button = new CustomDrawButton(normal_image_id,
149 pressed_image_id,
150 hover_image_id,
151 0);
152 gtk_widget_set_size_request(button->widget(),
153 panel::kPanelButtonSize,
154 panel::kPanelButtonSize);
155 gtk_widget_add_events(GTK_WIDGET(button->widget()), GDK_POINTER_MOTION_MASK);
156 g_signal_connect(button->widget(), "clicked",
157 G_CALLBACK(OnButtonClickedThunk), this);
158
159 std::string localized_tooltip = l10n_util::GetStringUTF8(tooltip_id);
160 gtk_widget_set_tooltip_text(button->widget(),
161 localized_tooltip.c_str());
162
163 GtkWidget* box = GetButtonHBox();
164 gtk_box_pack_start(GTK_BOX(box), button->widget(), FALSE, FALSE, 0);
165 return button;
166 }
167
168 void PanelTitlebarGtk::GetButtonResources(
169 panel::TitlebarButtonType button_type,
170 int* normal_image_id,
171 int* pressed_image_id,
172 int* hover_image_id,
173 int* tooltip_id) const {
174 switch (button_type) {
175 case panel::CLOSE_BUTTON:
176 *normal_image_id = IDR_PANEL_CLOSE;
177 *pressed_image_id = IDR_PANEL_CLOSE_C;
178 *hover_image_id = IDR_PANEL_CLOSE_H;
179 *tooltip_id = IDS_PANEL_CLOSE_TOOLTIP;
180 break;
181 case panel::MINIMIZE_BUTTON:
182 *normal_image_id = IDR_PANEL_MINIMIZE;
183 *pressed_image_id = IDR_PANEL_MINIMIZE_C;
184 *hover_image_id = IDR_PANEL_MINIMIZE_H;
185 *tooltip_id = IDS_PANEL_MINIMIZE_TOOLTIP;
186 break;
187 case panel::RESTORE_BUTTON:
188 *normal_image_id = IDR_PANEL_RESTORE;
189 *pressed_image_id = IDR_PANEL_RESTORE_C;
190 *hover_image_id = IDR_PANEL_RESTORE_H;
191 *tooltip_id = IDS_PANEL_RESTORE_TOOLTIP;
192 break;
193 }
194 }
195
196 GtkWidget* PanelTitlebarGtk::GetButtonHBox() {
197 if (!titlebar_right_buttons_hbox_) {
198 // We put the minimize/restore/close buttons in a vbox so they are top
199 // aligned (up to padding) and don't vertically stretch.
200 titlebar_right_buttons_hbox_ = gtk_hbox_new(FALSE, kPanelButtonSpacing);
201 gtk_box_pack_start(GTK_BOX(titlebar_right_buttons_vbox_),
202 titlebar_right_buttons_hbox_, FALSE, FALSE, 0);
203 }
204
205 return titlebar_right_buttons_hbox_;
206 }
207
208 void PanelTitlebarGtk::UpdateTitleAndIcon() {
209 std::string title_text =
210 base::UTF16ToUTF8(panel_gtk_->panel()->GetWindowTitle());
211
212 // Add the markup to show the title in the desired font.
213 gchar* escaped_title_text = g_markup_escape_text(title_text.c_str(), -1);
214 gchar* title_text_with_markup = g_strconcat(kTitleMarkupPrefix,
215 escaped_title_text,
216 kTitleMarkupSuffix,
217 NULL);
218 gtk_label_set_markup(GTK_LABEL(title_), title_text_with_markup);
219 g_free(escaped_title_text);
220 g_free(title_text_with_markup);
221
222 // Update icon from the web contents.
223 content::WebContents* web_contents = panel_gtk_->panel()->GetWebContents();
224 if (web_contents)
225 UpdateThrobber(web_contents);
226 }
227
228 void PanelTitlebarGtk::UpdateThrobber(
229 content::WebContents* web_contents) {
230 if (web_contents && web_contents->IsLoading()) {
231 GdkPixbuf* icon_pixbuf =
232 throbber_.GetNextFrame(web_contents->IsWaitingForResponse());
233 gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), icon_pixbuf);
234 } else {
235 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
236
237 gfx::Image icon = panel_gtk_->panel()->GetCurrentPageIcon();
238 if (icon.IsEmpty()) {
239 // Fallback to the Chromium icon if the page has no icon.
240 gtk_image_set_from_pixbuf(GTK_IMAGE(icon_),
241 rb.GetNativeImageNamed(IDR_PRODUCT_LOGO_16).ToGdkPixbuf());
242 } else {
243 gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), icon.ToGdkPixbuf());
244 }
245
246 throbber_.Reset();
247 }
248 }
249
250 void PanelTitlebarGtk::UpdateTextColor() {
251 GdkColor text_color = gfx::SkColorToGdkColor(GetTextColor());
252 gtk_util::SetLabelColor(title_, &text_color);
253 }
254
255 void PanelTitlebarGtk::UpdateMinimizeRestoreButtonVisibility() {
256 Panel* panel = panel_gtk_->panel();
257 gtk_widget_set_visible(minimize_button_->widget(),
258 panel->CanShowMinimizeButton());
259 gtk_widget_set_visible(restore_button_->widget(),
260 panel->CanShowRestoreButton());
261 }
262
263 void PanelTitlebarGtk::OnButtonClicked(GtkWidget* button) {
264 Panel* panel = panel_gtk_->panel();
265 if (close_button_->widget() == button) {
266 panel->Close();
267 return;
268 }
269
270 GdkEvent* event = gtk_get_current_event();
271 DCHECK(event && event->type == GDK_BUTTON_RELEASE);
272
273 if (minimize_button_->widget() == button) {
274 panel->OnMinimizeButtonClicked(
275 (event->button.state & GDK_CONTROL_MASK) ?
276 panel::APPLY_TO_ALL : panel::NO_MODIFIER);
277 } else if (restore_button_->widget() == button) {
278 panel->OnRestoreButtonClicked(
279 (event->button.state & GDK_CONTROL_MASK) ?
280 panel::APPLY_TO_ALL : panel::NO_MODIFIER);
281 panel->Activate();
282 }
283
284 gdk_event_free(event);
285 }
286
287 void PanelTitlebarGtk::SendEnterNotifyToCloseButtonIfUnderMouse() {
288 if (!close_button())
289 return;
290
291 gint x;
292 gint y;
293 GtkAllocation widget_allocation = close_button()->WidgetAllocation();
294 gtk_widget_get_pointer(GTK_WIDGET(close_button()->widget()), &x, &y);
295
296 gfx::Rect button_rect(0, 0, widget_allocation.width,
297 widget_allocation.height);
298 if (!button_rect.Contains(x, y)) {
299 // Mouse is not over the close button.
300 return;
301 }
302
303 // Create and emit an enter-notify-event on close button.
304 GValue return_value;
305 return_value.g_type = G_TYPE_BOOLEAN;
306 g_value_set_boolean(&return_value, false);
307
308 GdkEvent* event = gdk_event_new(GDK_ENTER_NOTIFY);
309 event->crossing.window =
310 gtk_button_get_event_window(GTK_BUTTON(close_button()->widget()));
311 event->crossing.send_event = FALSE;
312 event->crossing.subwindow = gtk_widget_get_window(close_button()->widget());
313 event->crossing.time = gtk_util::XTimeNow();
314 event->crossing.x = x;
315 event->crossing.y = y;
316 event->crossing.x_root = widget_allocation.x;
317 event->crossing.y_root = widget_allocation.y;
318 event->crossing.mode = GDK_CROSSING_NORMAL;
319 event->crossing.detail = GDK_NOTIFY_ANCESTOR;
320 event->crossing.focus = true;
321 event->crossing.state = 0;
322
323 g_signal_emit_by_name(GTK_OBJECT(close_button()->widget()),
324 "enter-notify-event", event,
325 &return_value);
326 }
327
328 GtkWidget* PanelTitlebarGtk::widget() const {
329 return container_;
330 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698