OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/gtk_custom_menu_item.h" | 5 #include "chrome/browser/gtk/gtk_custom_menu_item.h" |
6 | 6 |
7 #include "base/i18n/rtl.h" | 7 #include "base/i18n/rtl.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "chrome/browser/gtk/gtk_custom_menu.h" | 9 #include "chrome/browser/gtk/gtk_custom_menu.h" |
10 | 10 |
11 enum { | 11 enum { |
12 BUTTON_PUSHED, | 12 BUTTON_PUSHED, |
13 LAST_SIGNAL | 13 LAST_SIGNAL |
14 }; | 14 }; |
15 | 15 |
16 static guint custom_menu_item_signals[LAST_SIGNAL] = { 0 }; | 16 static guint custom_menu_item_signals[LAST_SIGNAL] = { 0 }; |
17 | 17 |
18 G_DEFINE_TYPE(GtkCustomMenuItem, gtk_custom_menu_item, GTK_TYPE_MENU_ITEM) | 18 G_DEFINE_TYPE(GtkCustomMenuItem, gtk_custom_menu_item, GTK_TYPE_MENU_ITEM) |
19 | 19 |
20 static void set_selected(GtkCustomMenuItem* item, GtkWidget* selected) { | 20 static void set_selected(GtkCustomMenuItem* item, GtkWidget* selected) { |
21 if (selected != item->currently_selected_button) { | 21 if (selected != item->currently_selected_button) { |
22 if (item->currently_selected_button) | 22 if (item->currently_selected_button) { |
23 gtk_widget_set_state(item->currently_selected_button, GTK_STATE_NORMAL); | 23 gtk_widget_set_state(item->currently_selected_button, GTK_STATE_NORMAL); |
| 24 gtk_widget_set_state( |
| 25 gtk_bin_get_child(GTK_BIN(item->currently_selected_button)), |
| 26 GTK_STATE_NORMAL); |
| 27 } |
24 | 28 |
25 item->currently_selected_button = selected; | 29 item->currently_selected_button = selected; |
26 if (item->currently_selected_button) | 30 if (item->currently_selected_button) { |
27 gtk_widget_set_state(item->currently_selected_button, GTK_STATE_SELECTED); | 31 gtk_widget_set_state(item->currently_selected_button, GTK_STATE_SELECTED); |
| 32 gtk_widget_set_state( |
| 33 gtk_bin_get_child(GTK_BIN(item->currently_selected_button)), |
| 34 GTK_STATE_PRELIGHT); |
| 35 } |
28 } | 36 } |
29 } | 37 } |
30 | 38 |
31 // When GtkButtons set the label text, they rebuild the widget hierarchy each | 39 // When GtkButtons set the label text, they rebuild the widget hierarchy each |
32 // and every time. Therefore, we can't just fish out the label from the button | 40 // and every time. Therefore, we can't just fish out the label from the button |
33 // and set some properties; we have to create this callback function that | 41 // and set some properties; we have to create this callback function that |
34 // listens on the button's "notify" signal, which is emitted right after the | 42 // listens on the button's "notify" signal, which is emitted right after the |
35 // label has been (re)created. (Label values can change dynamically.) | 43 // label has been (re)created. (Label values can change dynamically.) |
36 static void on_button_label_set(GObject* object) { | 44 static void on_button_label_set(GObject* object) { |
37 GtkButton* button = GTK_BUTTON(object); | 45 GtkButton* button = GTK_BUTTON(object); |
38 gtk_widget_set_sensitive(GTK_BIN(button)->child, FALSE); | 46 gtk_widget_set_sensitive(GTK_BIN(button)->child, FALSE); |
39 gtk_misc_set_padding(GTK_MISC(GTK_BIN(button)->child), 2, 0); | 47 gtk_misc_set_padding(GTK_MISC(GTK_BIN(button)->child), 2, 0); |
40 } | 48 } |
41 | 49 |
42 static void gtk_custom_menu_item_finalize(GObject *object); | 50 static void gtk_custom_menu_item_finalize(GObject *object); |
43 static gint gtk_custom_menu_item_expose(GtkWidget* widget, | 51 static gint gtk_custom_menu_item_expose(GtkWidget* widget, |
44 GdkEventExpose* event); | 52 GdkEventExpose* event); |
45 static gboolean gtk_custom_menu_item_hbox_expose(GtkWidget* widget, | 53 static gboolean gtk_custom_menu_item_hbox_expose(GtkWidget* widget, |
46 GdkEventExpose* event, | 54 GdkEventExpose* event, |
47 GtkCustomMenuItem* menu_item); | 55 GtkCustomMenuItem* menu_item); |
48 static void gtk_custom_menu_item_select(GtkItem *item); | 56 static void gtk_custom_menu_item_select(GtkItem *item); |
49 static void gtk_custom_menu_item_deselect(GtkItem *item); | 57 static void gtk_custom_menu_item_deselect(GtkItem *item); |
50 static void gtk_custom_menu_item_activate(GtkMenuItem* menu_item); | 58 static void gtk_custom_menu_item_activate(GtkMenuItem* menu_item); |
51 | 59 |
52 static void gtk_custom_menu_item_style_set(GtkCustomMenuItem* item, | |
53 GtkStyle* old_style) { | |
54 // Because several popular themes have no idea about styling buttons in menus | |
55 // (it's sort of a weird concept) and look like crap, we manually apply the | |
56 // menu item's prelight information to the button. | |
57 GtkStyle* style = gtk_widget_get_style(GTK_WIDGET(item)); | |
58 | |
59 for (GList* i = item->button_widgets; i; i = g_list_next(i)) { | |
60 // Set the button prelight colors. | |
61 GtkWidget* button = GTK_WIDGET(i->data); | |
62 gtk_widget_modify_fg(button, GTK_STATE_PRELIGHT, | |
63 &style->fg[GTK_STATE_PRELIGHT]); | |
64 gtk_widget_modify_bg(button, GTK_STATE_PRELIGHT, | |
65 &style->bg[GTK_STATE_PRELIGHT]); | |
66 gtk_widget_modify_text(button, GTK_STATE_PRELIGHT, | |
67 &style->text[GTK_STATE_PRELIGHT]); | |
68 gtk_widget_modify_base(button, GTK_STATE_PRELIGHT, | |
69 &style->base[GTK_STATE_PRELIGHT]); | |
70 } | |
71 } | |
72 | |
73 static void gtk_custom_menu_item_init(GtkCustomMenuItem* item) { | 60 static void gtk_custom_menu_item_init(GtkCustomMenuItem* item) { |
74 item->all_widgets = NULL; | 61 item->all_widgets = NULL; |
75 item->button_widgets = NULL; | 62 item->button_widgets = NULL; |
76 item->currently_selected_button = NULL; | 63 item->currently_selected_button = NULL; |
77 item->previously_selected_button = NULL; | 64 item->previously_selected_button = NULL; |
78 | 65 |
79 GtkWidget* menu_hbox = gtk_hbox_new(FALSE, 0); | 66 GtkWidget* menu_hbox = gtk_hbox_new(FALSE, 0); |
80 gtk_container_add(GTK_CONTAINER(item), menu_hbox); | 67 gtk_container_add(GTK_CONTAINER(item), menu_hbox); |
81 | 68 |
82 item->label = gtk_label_new(NULL); | 69 item->label = gtk_label_new(NULL); |
83 gtk_misc_set_alignment(GTK_MISC(item->label), 0.0, 0.5); | 70 gtk_misc_set_alignment(GTK_MISC(item->label), 0.0, 0.5); |
84 gtk_box_pack_start(GTK_BOX(menu_hbox), item->label, TRUE, TRUE, 0); | 71 gtk_box_pack_start(GTK_BOX(menu_hbox), item->label, TRUE, TRUE, 0); |
85 | 72 |
86 item->hbox = gtk_hbox_new(FALSE, 0); | 73 item->hbox = gtk_hbox_new(FALSE, 0); |
87 gtk_box_pack_end(GTK_BOX(menu_hbox), item->hbox, FALSE, FALSE, 0); | 74 gtk_box_pack_end(GTK_BOX(menu_hbox), item->hbox, FALSE, FALSE, 0); |
88 | 75 |
89 g_signal_connect(item, "style-set", | |
90 G_CALLBACK(gtk_custom_menu_item_style_set), NULL); | |
91 | |
92 g_signal_connect(item->hbox, "expose-event", | 76 g_signal_connect(item->hbox, "expose-event", |
93 G_CALLBACK(gtk_custom_menu_item_hbox_expose), | 77 G_CALLBACK(gtk_custom_menu_item_hbox_expose), |
94 item); | 78 item); |
95 | 79 |
96 gtk_widget_show_all(menu_hbox); | 80 gtk_widget_show_all(menu_hbox); |
97 } | 81 } |
98 | 82 |
99 static void gtk_custom_menu_item_class_init(GtkCustomMenuItemClass* klass) { | 83 static void gtk_custom_menu_item_class_init(GtkCustomMenuItemClass* klass) { |
100 GObjectClass* gobject_class = G_OBJECT_CLASS(klass); | 84 GObjectClass* gobject_class = G_OBJECT_CLASS(klass); |
101 GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass); | 85 GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass); |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 | 286 |
303 return button; | 287 return button; |
304 } | 288 } |
305 | 289 |
306 GtkWidget* gtk_custom_menu_item_add_button_label(GtkCustomMenuItem* menu_item, | 290 GtkWidget* gtk_custom_menu_item_add_button_label(GtkCustomMenuItem* menu_item, |
307 int command_id) { | 291 int command_id) { |
308 GtkWidget* button = gtk_button_new_with_label(""); | 292 GtkWidget* button = gtk_button_new_with_label(""); |
309 g_object_set_data(G_OBJECT(button), "command-id", | 293 g_object_set_data(G_OBJECT(button), "command-id", |
310 GINT_TO_POINTER(command_id)); | 294 GINT_TO_POINTER(command_id)); |
311 gtk_box_pack_start(GTK_BOX(menu_item->hbox), button, FALSE, FALSE, 0); | 295 gtk_box_pack_start(GTK_BOX(menu_item->hbox), button, FALSE, FALSE, 0); |
312 g_signal_connect(button, "notify", G_CALLBACK(on_button_label_set), NULL); | 296 g_signal_connect(button, "notify::label", |
| 297 G_CALLBACK(on_button_label_set), NULL); |
313 gtk_widget_show(button); | 298 gtk_widget_show(button); |
314 | 299 |
315 menu_item->all_widgets = g_list_append(menu_item->all_widgets, button); | 300 menu_item->all_widgets = g_list_append(menu_item->all_widgets, button); |
316 | 301 |
317 return button; | 302 return button; |
318 } | 303 } |
319 | 304 |
320 void gtk_custom_menu_item_add_space(GtkCustomMenuItem* menu_item) { | 305 void gtk_custom_menu_item_add_space(GtkCustomMenuItem* menu_item) { |
321 GtkWidget* fixed = gtk_fixed_new(); | 306 GtkWidget* fixed = gtk_fixed_new(); |
322 gtk_widget_set_size_request(fixed, 5, -1); | 307 gtk_widget_set_size_request(fixed, 5, -1); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 } | 388 } |
404 } | 389 } |
405 | 390 |
406 gtk_widget_queue_draw(GTK_WIDGET(menu_item)); | 391 gtk_widget_queue_draw(GTK_WIDGET(menu_item)); |
407 } | 392 } |
408 | 393 |
409 gboolean gtk_custom_menu_item_is_in_clickable_region( | 394 gboolean gtk_custom_menu_item_is_in_clickable_region( |
410 GtkCustomMenuItem* menu_item) { | 395 GtkCustomMenuItem* menu_item) { |
411 return menu_item->currently_selected_button != NULL; | 396 return menu_item->currently_selected_button != NULL; |
412 } | 397 } |
OLD | NEW |