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

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

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

Powered by Google App Engine
This is Rietveld 408576698