OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/gtk/menu_gtk.h" | 5 #include "chrome/browser/gtk/menu_gtk.h" |
6 | 6 |
| 7 #include "base/gfx/gtk_util.h" |
7 #include "base/logging.h" | 8 #include "base/logging.h" |
8 #include "base/string_util.h" | 9 #include "base/string_util.h" |
9 #include "chrome/common/l10n_util.h" | 10 #include "chrome/common/l10n_util.h" |
10 #include "skia/include/SkBitmap.h" | 11 #include "skia/include/SkBitmap.h" |
11 | 12 |
12 namespace { | 13 namespace { |
13 | 14 |
14 // GTK uses _ for accelerators. Windows uses & with && as an escape for &. | 15 // GTK uses _ for accelerators. Windows uses & with && as an escape for &. |
15 std::string ConvertAcceleratorsFromWindowsStyle(const std::string& label) { | 16 std::string ConvertAcceleratorsFromWindowsStyle(const std::string& label) { |
16 std::string ret; | 17 std::string ret; |
17 ret.reserve(label.length()); | 18 ret.reserve(label.length()); |
18 for (size_t i = 0; i < label.length(); ++i) { | 19 for (size_t i = 0; i < label.length(); ++i) { |
19 if ('&' == label[i]) { | 20 if ('&' == label[i]) { |
20 if (i + 1 < label.length() && '&' == label[i + 1]) { | 21 if (i + 1 < label.length() && '&' == label[i + 1]) { |
21 ret.push_back(label[i]); | 22 ret.push_back(label[i]); |
22 ++i; | 23 ++i; |
23 } else { | 24 } else { |
24 ret.push_back('_'); | 25 ret.push_back('_'); |
25 } | 26 } |
26 } else { | 27 } else { |
27 ret.push_back(label[i]); | 28 ret.push_back(label[i]); |
28 } | 29 } |
29 } | 30 } |
30 | 31 |
31 return ret; | 32 return ret; |
32 } | 33 } |
33 | 34 |
34 void FreePixels(guchar* pixels, gpointer data) { | |
35 free(data); | |
36 } | |
37 | |
38 // We have to copy the pixels and reverse their order manually. | |
39 GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap* bitmap) { | |
40 bitmap->lockPixels(); | |
41 int width = bitmap->width(); | |
42 int height = bitmap->height(); | |
43 int stride = bitmap->rowBytes(); | |
44 const guchar* orig_data = static_cast<guchar*>(bitmap->getPixels()); | |
45 guchar* data = static_cast<guchar*>(malloc(height * stride)); | |
46 | |
47 // Swap from BGRA to RGBA. | |
48 for (int i = 0; i < height; ++i) { | |
49 for (int j = 0; j < width; ++j) { | |
50 int idx = i * stride + j * 4; | |
51 data[idx] = orig_data[idx + 2]; | |
52 data[idx + 1] = orig_data[idx + 1]; | |
53 data[idx + 2] = orig_data[idx]; | |
54 data[idx + 3] = orig_data[idx + 3]; | |
55 } | |
56 } | |
57 | |
58 // This pixbuf takes ownership of our malloc()ed data and will | |
59 // free it for us when it is destroyed. | |
60 GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data( | |
61 data, | |
62 GDK_COLORSPACE_RGB, // the only colorspace gtk supports | |
63 true, // there is an alpha channel | |
64 8, | |
65 width, height, stride, &FreePixels, data); | |
66 | |
67 // Assume ownership of pixbuf. | |
68 g_object_ref_sink(pixbuf); | |
69 bitmap->unlockPixels(); | |
70 return pixbuf; | |
71 } | |
72 | |
73 } // namespace | 35 } // namespace |
74 | 36 |
75 MenuGtk::MenuGtk(MenuGtk::Delegate* delegate, | 37 MenuGtk::MenuGtk(MenuGtk::Delegate* delegate, |
76 const MenuCreateMaterial* menu_data, | 38 const MenuCreateMaterial* menu_data, |
77 GtkAccelGroup* accel_group) | 39 GtkAccelGroup* accel_group) |
78 : delegate_(delegate), | 40 : delegate_(delegate), |
79 accel_group_(accel_group), | 41 accel_group_(accel_group), |
80 menu_(gtk_menu_new()) { | 42 menu_(gtk_menu_new()) { |
81 g_object_ref_sink(menu_); | 43 g_object_ref_sink(menu_); |
82 BuildMenuIn(menu_, menu_data); | 44 BuildMenuIn(menu_, menu_data); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 // Note that the menu IDs start at 1, not 0. | 158 // Note that the menu IDs start at 1, not 0. |
197 for (int i = 1; i <= delegate_->GetItemCount(); ++i) { | 159 for (int i = 1; i <= delegate_->GetItemCount(); ++i) { |
198 GtkWidget* menu_item = NULL; | 160 GtkWidget* menu_item = NULL; |
199 | 161 |
200 if (delegate_->IsItemSeparator(i)) { | 162 if (delegate_->IsItemSeparator(i)) { |
201 menu_item = gtk_separator_menu_item_new(); | 163 menu_item = gtk_separator_menu_item_new(); |
202 } else if (delegate_->HasIcon(i)) { | 164 } else if (delegate_->HasIcon(i)) { |
203 menu_item = gtk_image_menu_item_new_with_label( | 165 menu_item = gtk_image_menu_item_new_with_label( |
204 delegate_->GetLabel(i).c_str()); | 166 delegate_->GetLabel(i).c_str()); |
205 const SkBitmap* icon = delegate_->GetIcon(i); | 167 const SkBitmap* icon = delegate_->GetIcon(i); |
206 GdkPixbuf* pixbuf = GdkPixbufFromSkBitmap(icon); | 168 GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(icon); |
207 GtkWidget* widget = gtk_image_new_from_pixbuf(pixbuf); | 169 GtkWidget* widget = gtk_image_new_from_pixbuf(pixbuf); |
208 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item), widget); | 170 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item), widget); |
209 g_object_unref(pixbuf); | 171 g_object_unref(pixbuf); |
210 } else { | 172 } else { |
211 menu_item = gtk_menu_item_new_with_label(delegate_->GetLabel(i).c_str()); | 173 menu_item = gtk_menu_item_new_with_label(delegate_->GetLabel(i).c_str()); |
212 } | 174 } |
213 | 175 |
214 g_object_set_data(G_OBJECT(menu_item), "menu-id", | 176 g_object_set_data(G_OBJECT(menu_item), "menu-id", |
215 reinterpret_cast<void*>(i)); | 177 reinterpret_cast<void*>(i)); |
216 | 178 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 widget, menu->delegate_->IsCommandEnabled(data->id)); | 265 widget, menu->delegate_->IsCommandEnabled(data->id)); |
304 | 266 |
305 GtkWidget* submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(widget)); | 267 GtkWidget* submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(widget)); |
306 if (submenu) { | 268 if (submenu) { |
307 gtk_container_foreach(GTK_CONTAINER(submenu), &MenuGtk::SetMenuItemInfo, | 269 gtk_container_foreach(GTK_CONTAINER(submenu), &MenuGtk::SetMenuItemInfo, |
308 raw_menu); | 270 raw_menu); |
309 } | 271 } |
310 } | 272 } |
311 } | 273 } |
312 } | 274 } |
OLD | NEW |