OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/ui/libgtk2ui/gtk2_ui.h" | 5 #include "chrome/browser/ui/libgtk2ui/gtk2_ui.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 #include <set> | 8 #include <set> |
9 | 9 |
10 #include <pango/pango.h> | 10 #include <pango/pango.h> |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 IDR_OMNIBOX_STAR, | 174 IDR_OMNIBOX_STAR, |
175 IDR_OMNIBOX_STAR_DARK, | 175 IDR_OMNIBOX_STAR_DARK, |
176 IDR_OMNIBOX_TTS, | 176 IDR_OMNIBOX_TTS, |
177 IDR_OMNIBOX_TTS_DARK, | 177 IDR_OMNIBOX_TTS_DARK, |
178 }; | 178 }; |
179 | 179 |
180 // This table converts button ids into a pair of gtk-stock id and state. | 180 // This table converts button ids into a pair of gtk-stock id and state. |
181 struct IDRGtkMapping { | 181 struct IDRGtkMapping { |
182 int idr; | 182 int idr; |
183 const char* stock_id; | 183 const char* stock_id; |
184 GtkStateType gtk_state; | 184 GtkStateFlags gtk_state; |
185 } const kGtkIcons[] = { | 185 } const kGtkIcons[] = { |
186 { IDR_BACK, GTK_STOCK_GO_BACK, GTK_STATE_NORMAL }, | 186 { IDR_BACK, GTK_STOCK_GO_BACK, GTK_STATE_FLAG_NORMAL }, |
187 { IDR_BACK_D, GTK_STOCK_GO_BACK, GTK_STATE_INSENSITIVE }, | 187 { IDR_BACK_D, GTK_STOCK_GO_BACK, GTK_STATE_FLAG_INSENSITIVE }, |
188 | 188 |
189 { IDR_FORWARD, GTK_STOCK_GO_FORWARD, GTK_STATE_NORMAL }, | 189 { IDR_FORWARD, GTK_STOCK_GO_FORWARD, GTK_STATE_FLAG_NORMAL }, |
190 { IDR_FORWARD_D, GTK_STOCK_GO_FORWARD, GTK_STATE_INSENSITIVE }, | 190 { IDR_FORWARD_D, GTK_STOCK_GO_FORWARD, GTK_STATE_FLAG_INSENSITIVE }, |
191 | 191 |
192 { IDR_HOME, GTK_STOCK_HOME, GTK_STATE_NORMAL }, | 192 { IDR_HOME, GTK_STOCK_HOME, GTK_STATE_FLAG_NORMAL }, |
193 | 193 |
194 { IDR_RELOAD, GTK_STOCK_REFRESH, GTK_STATE_NORMAL }, | 194 { IDR_RELOAD, GTK_STOCK_REFRESH, GTK_STATE_FLAG_NORMAL }, |
195 { IDR_RELOAD_D, GTK_STOCK_REFRESH, GTK_STATE_INSENSITIVE }, | 195 { IDR_RELOAD_D, GTK_STOCK_REFRESH, GTK_STATE_FLAG_INSENSITIVE }, |
196 | 196 |
197 { IDR_STOP, GTK_STOCK_STOP, GTK_STATE_NORMAL }, | 197 { IDR_STOP, GTK_STOCK_STOP, GTK_STATE_FLAG_NORMAL }, |
198 { IDR_STOP_D, GTK_STOCK_STOP, GTK_STATE_INSENSITIVE }, | 198 { IDR_STOP_D, GTK_STOCK_STOP, GTK_STATE_FLAG_INSENSITIVE }, |
199 }; | 199 }; |
200 | 200 |
201 // The image resources that will be tinted by the 'button' tint value. | 201 // The image resources that will be tinted by the 'button' tint value. |
202 const int kOtherToolbarButtonIDs[] = { | 202 const int kOtherToolbarButtonIDs[] = { |
203 IDR_TOOLBAR_BEZEL_HOVER, | 203 IDR_TOOLBAR_BEZEL_HOVER, |
204 IDR_TOOLBAR_BEZEL_PRESSED, | 204 IDR_TOOLBAR_BEZEL_PRESSED, |
205 IDR_BROWSER_ACTIONS_OVERFLOW, | 205 IDR_BROWSER_ACTIONS_OVERFLOW, |
206 | 206 |
207 // TODO(erg): The dropdown arrow should be tinted because we're injecting | 207 // TODO(erg): The dropdown arrow should be tinted because we're injecting |
208 // various background GTK colors, but the code that accesses them needs to be | 208 // various background GTK colors, but the code that accesses them needs to be |
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 if (theme_thumb_active && theme_thumb_inactive && theme_trough_color) { | 765 if (theme_thumb_active && theme_thumb_inactive && theme_trough_color) { |
766 *thumb_active_color = *theme_thumb_active; | 766 *thumb_active_color = *theme_thumb_active; |
767 *thumb_inactive_color = *theme_thumb_inactive; | 767 *thumb_inactive_color = *theme_thumb_inactive; |
768 *track_color = *theme_trough_color; | 768 *track_color = *theme_trough_color; |
769 | 769 |
770 gdk_color_free(theme_thumb_active); | 770 gdk_color_free(theme_thumb_active); |
771 gdk_color_free(theme_thumb_inactive); | 771 gdk_color_free(theme_thumb_inactive); |
772 gdk_color_free(theme_trough_color); | 772 gdk_color_free(theme_trough_color); |
773 return; | 773 return; |
774 } | 774 } |
775 | |
776 // Create window containing scrollbar elements | |
777 GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP); | |
778 GtkWidget* fixed = gtk_fixed_new(); | |
779 GtkWidget* scrollbar = gtk_hscrollbar_new(NULL); | |
780 gtk_container_add(GTK_CONTAINER(window), fixed); | |
781 gtk_container_add(GTK_CONTAINER(fixed), scrollbar); | |
782 gtk_widget_realize(window); | |
783 gtk_widget_realize(scrollbar); | |
784 | |
785 // Draw scrollbar thumb part and track into offscreen image | |
786 const int kWidth = 100; | |
787 const int kHeight = 20; | |
788 GtkStyle* style = gtk_rc_get_style(scrollbar); | |
789 GdkWindow* gdk_window = gtk_widget_get_window(window); | |
790 GdkPixmap* pm = gdk_pixmap_new(gdk_window, kWidth, kHeight, -1); | |
791 GdkRectangle rect = { 0, 0, kWidth, kHeight }; | |
792 unsigned char data[3 * kWidth * kHeight]; | |
793 for (int i = 0; i < 3; ++i) { | |
794 if (i < 2) { | |
795 // Thumb part | |
796 gtk_paint_slider(style, pm, | |
797 i == 0 ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL, | |
798 GTK_SHADOW_OUT, &rect, scrollbar, "slider", 0, 0, | |
799 kWidth, kHeight, GTK_ORIENTATION_HORIZONTAL); | |
800 } else { | |
801 // Track | |
802 gtk_paint_box(style, pm, GTK_STATE_ACTIVE, GTK_SHADOW_IN, &rect, | |
803 scrollbar, "trough-upper", 0, 0, kWidth, kHeight); | |
804 } | |
805 GdkPixbuf* pb = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, | |
806 FALSE, 8, kWidth, kHeight, | |
807 3 * kWidth, 0, 0); | |
808 gdk_pixbuf_get_from_drawable(pb, pm, NULL, 0, 0, 0, 0, kWidth, kHeight); | |
809 | |
810 // Sample pixels | |
811 int components[3] = { 0 }; | |
812 for (int y = 2; y < kHeight - 2; ++y) { | |
813 for (int c = 0; c < 3; ++c) { | |
814 // Sample a vertical slice of pixels at about one-thirds from the | |
815 // left edge. This allows us to avoid any fixed graphics that might be | |
816 // located at the edges or in the center of the scrollbar. | |
817 // Each pixel is made up of a red, green, and blue component; taking up | |
818 // a total of three bytes. | |
819 components[c] += data[3 * (kWidth / 3 + y * kWidth) + c]; | |
820 } | |
821 } | |
822 GdkColor* color = i == 0 ? thumb_active_color : | |
823 i == 1 ? thumb_inactive_color : | |
824 track_color; | |
825 color->pixel = 0; | |
826 // We sampled pixels across the full height of the image, ignoring a two | |
827 // pixel border. In some themes, the border has a completely different | |
828 // color which we do not want to factor into our average color computation. | |
829 // | |
830 // We now need to scale the colors from the 0..255 range, to the wider | |
831 // 0..65535 range, and we need to actually compute the average color; so, | |
832 // we divide by the total number of pixels in the sample. | |
833 color->red = components[0] * 65535 / (255 * (kHeight - 4)); | |
834 color->green = components[1] * 65535 / (255 * (kHeight - 4)); | |
835 color->blue = components[2] * 65535 / (255 * (kHeight - 4)); | |
836 | |
837 g_object_unref(pb); | |
838 } | |
839 g_object_unref(pm); | |
840 | |
841 gtk_widget_destroy(window); | |
842 | |
843 // Override any of the default colors with ones that were specified by the | |
844 // theme. | |
845 if (theme_thumb_active) { | |
846 *thumb_active_color = *theme_thumb_active; | |
847 gdk_color_free(theme_thumb_active); | |
848 } | |
849 | |
850 if (theme_thumb_inactive) { | |
851 *thumb_inactive_color = *theme_thumb_inactive; | |
852 gdk_color_free(theme_thumb_inactive); | |
853 } | |
854 | |
855 if (theme_trough_color) { | |
856 *track_color = *theme_trough_color; | |
857 gdk_color_free(theme_trough_color); | |
858 } | |
859 } | 775 } |
860 | 776 |
861 void Gtk2UI::LoadGtkValues() { | 777 void Gtk2UI::LoadGtkValues() { |
862 // TODO(erg): GtkThemeService had a comment here about having to muck with | 778 // TODO(erg): GtkThemeService had a comment here about having to muck with |
863 // the raw Prefs object to remove prefs::kCurrentThemeImages or else we'd | 779 // the raw Prefs object to remove prefs::kCurrentThemeImages or else we'd |
864 // regress startup time. Figure out how to do that when we can't access the | 780 // regress startup time. Figure out how to do that when we can't access the |
865 // prefs system from here. | 781 // prefs system from here. |
866 | 782 |
867 GtkStyle* frame_style = gtk_rc_get_style(fake_frame_); | 783 GtkStyle* frame_style = gtk_rc_get_style(fake_frame_); |
868 | 784 |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1136 case IDR_FORWARD: | 1052 case IDR_FORWARD: |
1137 case IDR_FORWARD_D: | 1053 case IDR_FORWARD_D: |
1138 case IDR_HOME: | 1054 case IDR_HOME: |
1139 case IDR_RELOAD: | 1055 case IDR_RELOAD: |
1140 case IDR_RELOAD_D: | 1056 case IDR_RELOAD_D: |
1141 case IDR_STOP: | 1057 case IDR_STOP: |
1142 case IDR_STOP_D: { | 1058 case IDR_STOP_D: { |
1143 return GenerateGTKIcon(id); | 1059 return GenerateGTKIcon(id); |
1144 } | 1060 } |
1145 case IDR_TOOLBAR_BEZEL_HOVER: | 1061 case IDR_TOOLBAR_BEZEL_HOVER: |
1146 return GenerateToolbarBezel(GTK_STATE_PRELIGHT, IDR_TOOLBAR_BEZEL_HOVER); | 1062 return GenerateToolbarBezel(GTK_STATE_FLAG_PRELIGHT, IDR_TOOLBAR_BEZEL_HOV
ER); |
1147 case IDR_TOOLBAR_BEZEL_PRESSED: | 1063 case IDR_TOOLBAR_BEZEL_PRESSED: |
1148 return GenerateToolbarBezel(GTK_STATE_ACTIVE, IDR_TOOLBAR_BEZEL_PRESSED); | 1064 return GenerateToolbarBezel(GTK_STATE_FLAG_ACTIVE, IDR_TOOLBAR_BEZEL_PRESS
ED); |
1149 default: { | 1065 default: { |
1150 return GenerateTintedIcon(id, button_tint_); | 1066 return GenerateTintedIcon(id, button_tint_); |
1151 } | 1067 } |
1152 } | 1068 } |
1153 | 1069 |
1154 return SkBitmap(); | 1070 return SkBitmap(); |
1155 } | 1071 } |
1156 | 1072 |
1157 SkBitmap Gtk2UI::GenerateFrameImage( | 1073 SkBitmap Gtk2UI::GenerateFrameImage( |
1158 int color_id, | 1074 int color_id, |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1206 SkBitmap Gtk2UI::GenerateTintedIcon( | 1122 SkBitmap Gtk2UI::GenerateTintedIcon( |
1207 int base_id, | 1123 int base_id, |
1208 const color_utils::HSL& tint) const { | 1124 const color_utils::HSL& tint) const { |
1209 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 1125 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
1210 return SkBitmapOperations::CreateHSLShiftedBitmap( | 1126 return SkBitmapOperations::CreateHSLShiftedBitmap( |
1211 rb.GetImageNamed(base_id).AsBitmap(), tint); | 1127 rb.GetImageNamed(base_id).AsBitmap(), tint); |
1212 } | 1128 } |
1213 | 1129 |
1214 SkBitmap Gtk2UI::GenerateGTKIcon(int base_id) const { | 1130 SkBitmap Gtk2UI::GenerateGTKIcon(int base_id) const { |
1215 const char* stock_id = NULL; | 1131 const char* stock_id = NULL; |
1216 GtkStateType gtk_state = GTK_STATE_NORMAL; | 1132 GtkStateFlags gtk_state = GTK_STATE_FLAG_NORMAL; |
1217 for (unsigned int i = 0; i < arraysize(kGtkIcons); ++i) { | 1133 for (unsigned int i = 0; i < arraysize(kGtkIcons); ++i) { |
1218 if (kGtkIcons[i].idr == base_id) { | 1134 if (kGtkIcons[i].idr == base_id) { |
1219 stock_id = kGtkIcons[i].stock_id; | 1135 stock_id = kGtkIcons[i].stock_id; |
1220 gtk_state = kGtkIcons[i].gtk_state; | 1136 gtk_state = kGtkIcons[i].gtk_state; |
1221 break; | 1137 break; |
1222 } | 1138 } |
1223 } | 1139 } |
1224 DCHECK(stock_id); | 1140 DCHECK(stock_id); |
1225 | 1141 |
1226 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 1142 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
1227 SkBitmap default_bitmap = rb.GetImageNamed(base_id).AsBitmap(); | 1143 SkBitmap default_bitmap = rb.GetImageNamed(base_id).AsBitmap(); |
1228 | 1144 |
1229 gtk_widget_ensure_style(fake_frame_); | 1145 gtk_widget_ensure_style(fake_frame_); |
1230 GtkStyle* style = gtk_widget_get_style(fake_frame_); | 1146 GtkStyle* style = gtk_widget_get_style(fake_frame_); |
1231 GtkIconSet* icon_set = gtk_style_lookup_icon_set(style, stock_id); | 1147 GtkIconSet* icon_set = gtk_style_lookup_icon_set(style, stock_id); |
1232 if (!icon_set) | 1148 if (!icon_set) |
1233 return default_bitmap; | 1149 return default_bitmap; |
1234 | 1150 |
1235 // Ask GTK to render the icon to a buffer, which we will steal from. | 1151 // Ask GTK to render the icon to a buffer, which we will steal from. |
1236 GdkPixbuf* gdk_icon = gtk_icon_set_render_icon( | 1152 GdkPixbuf* gdk_icon = gtk_icon_set_render_icon( |
1237 icon_set, | 1153 icon_set, |
1238 style, | 1154 style, |
1239 base::i18n::IsRTL() ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR, | 1155 base::i18n::IsRTL() ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR, |
1240 gtk_state, | 1156 gtk_state == GTK_STATE_FLAG_INSENSITIVE ? GTK_STATE_INSENSITIVE : GTK_STAT
E_NORMAL, |
1241 GTK_ICON_SIZE_SMALL_TOOLBAR, | 1157 GTK_ICON_SIZE_SMALL_TOOLBAR, |
1242 fake_frame_, | 1158 fake_frame_, |
1243 NULL); | 1159 NULL); |
1244 | 1160 |
1245 if (!gdk_icon) { | 1161 if (!gdk_icon) { |
1246 // This can theoretically happen if an icon theme doesn't provide a | 1162 // This can theoretically happen if an icon theme doesn't provide a |
1247 // specific image. This should realistically never happen, but I bet there | 1163 // specific image. This should realistically never happen, but I bet there |
1248 // are some theme authors who don't reliably provide all icons. | 1164 // are some theme authors who don't reliably provide all icons. |
1249 return default_bitmap; | 1165 return default_bitmap; |
1250 } | 1166 } |
1251 | 1167 |
1252 SkBitmap retval; | 1168 SkBitmap retval; |
1253 retval.allocN32Pixels(default_bitmap.width(), default_bitmap.height()); | 1169 retval.allocN32Pixels(default_bitmap.width(), default_bitmap.height()); |
1254 retval.eraseColor(0); | 1170 retval.eraseColor(0); |
1255 | 1171 |
1256 const SkBitmap icon = GdkPixbufToImageSkia(gdk_icon); | 1172 const SkBitmap icon = GdkPixbufToImageSkia(gdk_icon); |
1257 g_object_unref(gdk_icon); | 1173 g_object_unref(gdk_icon); |
1258 | 1174 |
1259 SkCanvas canvas(retval); | 1175 SkCanvas canvas(retval); |
1260 | 1176 |
1261 if (gtk_state == GTK_STATE_ACTIVE || gtk_state == GTK_STATE_PRELIGHT) { | |
1262 SkBitmap border = DrawGtkButtonBorder(gtk_state, | |
1263 false, | |
1264 false, | |
1265 default_bitmap.width(), | |
1266 default_bitmap.height()); | |
1267 canvas.drawBitmap(border, 0, 0); | |
1268 } | |
1269 | |
1270 canvas.drawBitmap(icon, | 1177 canvas.drawBitmap(icon, |
1271 (default_bitmap.width() / 2) - (icon.width() / 2), | 1178 (default_bitmap.width() / 2) - (icon.width() / 2), |
1272 (default_bitmap.height() / 2) - (icon.height() / 2)); | 1179 (default_bitmap.height() / 2) - (icon.height() / 2)); |
1273 | 1180 |
1274 return retval; | 1181 return retval; |
1275 } | 1182 } |
1276 | 1183 |
1277 SkBitmap Gtk2UI::GenerateToolbarBezel(int gtk_state, int sizing_idr) const { | 1184 SkBitmap Gtk2UI::GenerateToolbarBezel(int gtk_state, int sizing_idr) const { |
1278 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 1185 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
1279 SkBitmap default_bitmap = | 1186 SkBitmap default_bitmap = |
1280 rb.GetImageNamed(sizing_idr).AsBitmap(); | 1187 rb.GetImageNamed(sizing_idr).AsBitmap(); |
1281 | 1188 |
1282 SkBitmap retval; | 1189 SkBitmap retval; |
1283 retval.allocN32Pixels(default_bitmap.width(), default_bitmap.height()); | 1190 retval.allocN32Pixels(default_bitmap.width(), default_bitmap.height()); |
1284 retval.eraseColor(0); | 1191 retval.eraseColor(0); |
1285 | 1192 |
1286 SkCanvas canvas(retval); | 1193 SkCanvas canvas(retval); |
1287 SkBitmap border = DrawGtkButtonBorder( | 1194 SkBitmap border = DrawGtkButtonBorder( |
1288 gtk_state, | 1195 gtk_state, |
1289 false, | |
1290 false, | |
1291 default_bitmap.width(), | 1196 default_bitmap.width(), |
1292 default_bitmap.height()); | 1197 default_bitmap.height()); |
1293 canvas.drawBitmap(border, 0, 0); | 1198 canvas.drawBitmap(border, 0, 0); |
1294 | 1199 |
1295 return retval; | 1200 return retval; |
1296 } | 1201 } |
1297 | 1202 |
1298 void Gtk2UI::GetNormalButtonTintHSL(color_utils::HSL* tint) const { | 1203 void Gtk2UI::GetNormalButtonTintHSL(color_utils::HSL* tint) const { |
1299 GtkStyle* window_style = gtk_rc_get_style(fake_window_); | 1204 GtkStyle* window_style = gtk_rc_get_style(fake_window_); |
1300 const GdkColor accent_gdk_color = window_style->bg[GTK_STATE_SELECTED]; | 1205 const GdkColor accent_gdk_color = window_style->bg[GTK_STATE_SELECTED]; |
(...skipping 19 matching lines...) Expand all Loading... |
1320 void Gtk2UI::GetSelectedEntryForegroundHSL(color_utils::HSL* tint) const { | 1225 void Gtk2UI::GetSelectedEntryForegroundHSL(color_utils::HSL* tint) const { |
1321 // The simplest of all the tints. We just use the selected text in the entry | 1226 // The simplest of all the tints. We just use the selected text in the entry |
1322 // since the icons tinted this way will only be displayed against | 1227 // since the icons tinted this way will only be displayed against |
1323 // base[GTK_STATE_SELECTED]. | 1228 // base[GTK_STATE_SELECTED]. |
1324 GtkStyle* style = gtk_rc_get_style(fake_entry_.get()); | 1229 GtkStyle* style = gtk_rc_get_style(fake_entry_.get()); |
1325 const GdkColor color = style->text[GTK_STATE_SELECTED]; | 1230 const GdkColor color = style->text[GTK_STATE_SELECTED]; |
1326 color_utils::SkColorToHSL(GdkColorToSkColor(color), tint); | 1231 color_utils::SkColorToHSL(GdkColorToSkColor(color), tint); |
1327 } | 1232 } |
1328 | 1233 |
1329 SkBitmap Gtk2UI::DrawGtkButtonBorder(int gtk_state, | 1234 SkBitmap Gtk2UI::DrawGtkButtonBorder(int gtk_state, |
1330 bool focused, | |
1331 bool call_to_action, | |
1332 int width, | 1235 int width, |
1333 int height) const { | 1236 int height) const { |
| 1237 SkBitmap border; |
| 1238 border.allocN32Pixels(width, height); |
| 1239 border.eraseColor(0); |
| 1240 |
1334 // Create a temporary GTK button to snapshot | 1241 // Create a temporary GTK button to snapshot |
1335 GtkWidget* window = gtk_offscreen_window_new(); | 1242 GtkWidget* window = gtk_offscreen_window_new(); |
1336 GtkWidget* button = gtk_button_new(); | 1243 GtkWidget* button = gtk_toggle_button_new(); |
| 1244 |
| 1245 if (gtk_state & GTK_STATE_FLAG_ACTIVE) |
| 1246 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), true); |
| 1247 |
1337 gtk_widget_set_size_request(button, width, height); | 1248 gtk_widget_set_size_request(button, width, height); |
1338 gtk_container_add(GTK_CONTAINER(window), button); | 1249 gtk_container_add(GTK_CONTAINER(window), button); |
1339 gtk_widget_realize(window); | 1250 gtk_widget_realize(window); |
1340 gtk_widget_realize(button); | 1251 gtk_widget_realize(button); |
1341 gtk_widget_show(button); | 1252 gtk_widget_show(button); |
1342 gtk_widget_show(window); | 1253 gtk_widget_show(window); |
1343 | 1254 |
1344 if (call_to_action) | 1255 gtk_widget_set_state_flags(button, (GtkStateFlags)gtk_state, FALSE); |
1345 GTK_WIDGET_SET_FLAGS(button, GTK_HAS_DEFAULT); | |
1346 | 1256 |
1347 if (focused) { | 1257 cairo_surface_t* surface = cairo_image_surface_create_for_data( |
1348 // We can't just use gtk_widget_grab_focus() here because that sets | 1258 static_cast<unsigned char*>(border.getAddr(0, 0)), |
1349 // gtk_widget_is_focus(), but not gtk_widget_has_focus(), which is what the | 1259 CAIRO_FORMAT_ARGB32, |
1350 // GtkButton's paint checks. | 1260 width, height, |
1351 GTK_WIDGET_SET_FLAGS(button, GTK_HAS_FOCUS); | 1261 width * 4); |
1352 } | 1262 cairo_t* cr = cairo_create(surface); |
1353 | 1263 |
1354 gtk_widget_set_state(button, static_cast<GtkStateType>(gtk_state)); | 1264 gtk_widget_draw(button, cr); |
1355 | 1265 |
1356 GdkPixmap* pixmap; | 1266 cairo_destroy(cr); |
1357 { | 1267 cairo_surface_destroy(surface); |
1358 // http://crbug.com/346740 | |
1359 ANNOTATE_SCOPED_MEMORY_LEAK; | |
1360 pixmap = gtk_widget_get_snapshot(button, NULL); | |
1361 } | |
1362 int w, h; | |
1363 gdk_drawable_get_size(GDK_DRAWABLE(pixmap), &w, &h); | |
1364 DCHECK_EQ(w, width); | |
1365 DCHECK_EQ(h, height); | |
1366 | |
1367 // We render the Pixmap to a Pixbuf. This can be slow, as we're scrapping | |
1368 // bits from X. | |
1369 GdkColormap* colormap = gdk_drawable_get_colormap(pixmap); | |
1370 GdkPixbuf* pixbuf = gdk_pixbuf_get_from_drawable(NULL, | |
1371 GDK_DRAWABLE(pixmap), | |
1372 colormap, | |
1373 0, 0, 0, 0, w, h); | |
1374 | |
1375 // Finally, we convert our pixbuf into a type we can use. | |
1376 SkBitmap border = GdkPixbufToImageSkia(pixbuf); | |
1377 g_object_unref(pixbuf); | |
1378 g_object_unref(pixmap); | |
1379 gtk_widget_destroy(window); | 1268 gtk_widget_destroy(window); |
1380 | 1269 |
1381 return border; | 1270 return border; |
1382 } | 1271 } |
1383 | 1272 |
1384 void Gtk2UI::ClearAllThemeData() { | 1273 void Gtk2UI::ClearAllThemeData() { |
1385 gtk_images_.clear(); | 1274 gtk_images_.clear(); |
1386 } | 1275 } |
1387 | 1276 |
1388 void Gtk2UI::UpdateDefaultFont(const PangoFontDescription* desc) { | 1277 void Gtk2UI::UpdateDefaultFont(const PangoFontDescription* desc) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1437 float scale = GetFontDPI() / GetBaseDPI(); | 1326 float scale = GetFontDPI() / GetBaseDPI(); |
1438 // Round to 1 decimal, e.g. to 1.4. | 1327 // Round to 1 decimal, e.g. to 1.4. |
1439 return roundf(scale * 10) / 10; | 1328 return roundf(scale * 10) / 10; |
1440 } | 1329 } |
1441 | 1330 |
1442 } // namespace libgtk2ui | 1331 } // namespace libgtk2ui |
1443 | 1332 |
1444 views::LinuxUI* BuildGtk2UI() { | 1333 views::LinuxUI* BuildGtk2UI() { |
1445 return new libgtk2ui::Gtk2UI; | 1334 return new libgtk2ui::Gtk2UI; |
1446 } | 1335 } |
OLD | NEW |