OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/gtk/avatar_menu_item_gtk.h" | 5 #include "chrome/browser/ui/gtk/avatar_menu_item_gtk.h" |
6 | 6 |
| 7 #include <gdk/gdkkeysyms.h> |
| 8 |
7 #include "base/bind.h" | 9 #include "base/bind.h" |
8 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
9 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
10 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h" | 12 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h" |
11 #include "chrome/browser/ui/gtk/gtk_theme_service.h" | 13 #include "chrome/browser/ui/gtk/gtk_theme_service.h" |
12 #include "chrome/browser/ui/gtk/gtk_util.h" | 14 #include "chrome/browser/ui/gtk/gtk_util.h" |
13 #include "chrome/common/chrome_notification_types.h" | 15 #include "chrome/common/chrome_notification_types.h" |
14 #include "content/public/browser/notification_source.h" | 16 #include "content/public/browser/notification_source.h" |
15 #include "grit/generated_resources.h" | 17 #include "grit/generated_resources.h" |
16 #include "grit/theme_resources.h" | 18 #include "grit/theme_resources.h" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 // try to destroy this AvatarMenuItemGtk. | 77 // try to destroy this AvatarMenuItemGtk. |
76 // This is not OK to do this from the signal handler, so we'll | 78 // This is not OK to do this from the signal handler, so we'll |
77 // defer it. | 79 // defer it. |
78 MessageLoop::current()->PostTask( | 80 MessageLoop::current()->PostTask( |
79 FROM_HERE, | 81 FROM_HERE, |
80 base::Bind(&AvatarMenuItemGtk::OpenProfile, | 82 base::Bind(&AvatarMenuItemGtk::OpenProfile, |
81 weak_factory_.GetWeakPtr())); | 83 weak_factory_.GetWeakPtr())); |
82 return FALSE; | 84 return FALSE; |
83 } | 85 } |
84 | 86 |
| 87 gboolean AvatarMenuItemGtk::OnProfileKeyPress(GtkWidget* widget, |
| 88 GdkEventKey* event) { |
| 89 // delegate_->EditProfile() will close the avatar bubble which in turn |
| 90 // try to destroy this AvatarMenuItemGtk. |
| 91 // This is not OK to do this from the signal handler, so we'll |
| 92 // defer it. |
| 93 if (event->keyval == GDK_Return || |
| 94 event->keyval == GDK_ISO_Enter || |
| 95 event->keyval == GDK_KP_Enter) { |
| 96 if (item_.active) |
| 97 MessageLoop::current()->PostTask( |
| 98 FROM_HERE, |
| 99 base::Bind(&AvatarMenuItemGtk::EditProfile, |
| 100 weak_factory_.GetWeakPtr())); |
| 101 else |
| 102 MessageLoop::current()->PostTask( |
| 103 FROM_HERE, |
| 104 base::Bind(&AvatarMenuItemGtk::OpenProfile, |
| 105 weak_factory_.GetWeakPtr())); |
| 106 } |
| 107 |
| 108 return FALSE; |
| 109 } |
| 110 |
| 111 void AvatarMenuItemGtk::ShowStatusLabel() { |
| 112 gtk_widget_show(status_label_); |
| 113 gtk_widget_hide(link_alignment_); |
| 114 } |
| 115 |
| 116 void AvatarMenuItemGtk::ShowEditLink() { |
| 117 gtk_widget_hide(status_label_); |
| 118 gtk_widget_show(link_alignment_); |
| 119 } |
| 120 |
| 121 gboolean AvatarMenuItemGtk::OnProfileFocusIn(GtkWidget* widget, |
| 122 GdkEventFocus* event) { |
| 123 gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &highlighted_color_); |
| 124 if (item_.active) |
| 125 ShowEditLink(); |
| 126 |
| 127 return FALSE; |
| 128 } |
| 129 |
| 130 gboolean AvatarMenuItemGtk::OnProfileFocusOut(GtkWidget* widget, |
| 131 GdkEventFocus* event) { |
| 132 gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, unhighlighted_color_); |
| 133 if (item_.active) |
| 134 ShowStatusLabel(); |
| 135 |
| 136 return FALSE; |
| 137 } |
| 138 |
85 gboolean AvatarMenuItemGtk::OnProfileEnter(GtkWidget* widget, | 139 gboolean AvatarMenuItemGtk::OnProfileEnter(GtkWidget* widget, |
86 GdkEventCrossing* event) { | 140 GdkEventCrossing* event) { |
87 if (event->detail == GDK_NOTIFY_INFERIOR) | 141 if (event->detail == GDK_NOTIFY_INFERIOR) |
88 return FALSE; | 142 return FALSE; |
89 | 143 |
90 gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &highlighted_color_); | 144 gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &highlighted_color_); |
91 if (item_.active) { | 145 if (item_.active) |
92 gtk_widget_hide(status_label_); | 146 ShowEditLink(); |
93 gtk_widget_show(link_alignment_); | |
94 } | |
95 | 147 |
96 return FALSE; | 148 return FALSE; |
97 } | 149 } |
98 | 150 |
99 gboolean AvatarMenuItemGtk::OnProfileLeave(GtkWidget* widget, | 151 gboolean AvatarMenuItemGtk::OnProfileLeave(GtkWidget* widget, |
100 GdkEventCrossing* event) { | 152 GdkEventCrossing* event) { |
101 if (event->detail == GDK_NOTIFY_INFERIOR) | 153 if (event->detail == GDK_NOTIFY_INFERIOR) |
102 return FALSE; | 154 return FALSE; |
103 | 155 |
104 gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, unhighlighted_color_); | 156 gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, unhighlighted_color_); |
105 if (item_.active) { | 157 if (item_.active) |
106 gtk_widget_show(status_label_); | 158 ShowStatusLabel(); |
107 gtk_widget_hide(link_alignment_); | |
108 } | |
109 | 159 |
110 return FALSE; | 160 return FALSE; |
111 } | 161 } |
112 | 162 |
113 void AvatarMenuItemGtk::EditProfile() { | 163 void AvatarMenuItemGtk::EditProfile() { |
114 delegate_->EditProfile(item_index_); | 164 delegate_->EditProfile(item_index_); |
115 } | 165 } |
116 | 166 |
117 void AvatarMenuItemGtk::Observe(int type, | 167 void AvatarMenuItemGtk::Observe(int type, |
118 const content::NotificationSource& source, | 168 const content::NotificationSource& source, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 | 203 |
154 void AvatarMenuItemGtk::Init(GtkThemeService* theme_service) { | 204 void AvatarMenuItemGtk::Init(GtkThemeService* theme_service) { |
155 widget_.Own(gtk_event_box_new()); | 205 widget_.Own(gtk_event_box_new()); |
156 | 206 |
157 g_signal_connect(widget_.get(), "button-press-event", | 207 g_signal_connect(widget_.get(), "button-press-event", |
158 G_CALLBACK(OnProfileClickThunk), this); | 208 G_CALLBACK(OnProfileClickThunk), this); |
159 g_signal_connect(widget_.get(), "enter-notify-event", | 209 g_signal_connect(widget_.get(), "enter-notify-event", |
160 G_CALLBACK(OnProfileEnterThunk), this); | 210 G_CALLBACK(OnProfileEnterThunk), this); |
161 g_signal_connect(widget_.get(), "leave-notify-event", | 211 g_signal_connect(widget_.get(), "leave-notify-event", |
162 G_CALLBACK(OnProfileLeaveThunk), this); | 212 G_CALLBACK(OnProfileLeaveThunk), this); |
| 213 g_signal_connect(widget_.get(), "focus-in-event", |
| 214 G_CALLBACK(OnProfileFocusInThunk), this); |
| 215 g_signal_connect(widget_.get(), "focus-out-event", |
| 216 G_CALLBACK(OnProfileFocusOutThunk), this); |
| 217 g_signal_connect(widget_.get(), "key-press-event", |
| 218 G_CALLBACK(OnProfileKeyPressThunk), this); |
163 | 219 |
164 GtkWidget* item_hbox = gtk_hbox_new(FALSE, ui::kControlSpacing); | 220 GtkWidget* item_hbox = gtk_hbox_new(FALSE, ui::kControlSpacing); |
165 GdkPixbuf* avatar_pixbuf = NULL; | 221 GdkPixbuf* avatar_pixbuf = NULL; |
166 | 222 |
167 // If this profile is active then draw a check mark on the bottom right | 223 // If this profile is active then draw a check mark on the bottom right |
168 // of the profile icon. | 224 // of the profile icon. |
169 if (item_.active) { | 225 if (item_.active) { |
170 const SkBitmap* avatar_image = item_.icon.ToSkBitmap(); | 226 const SkBitmap* avatar_image = item_.icon.ToSkBitmap(); |
171 gfx::CanvasSkia canvas(avatar_image->width(), | 227 gfx::CanvasSkia canvas(avatar_image->width(), |
172 avatar_image->height(), | 228 avatar_image->height(), |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 | 295 |
240 GtkSizeGroup* size_group = gtk_size_group_new(GTK_SIZE_GROUP_BOTH); | 296 GtkSizeGroup* size_group = gtk_size_group_new(GTK_SIZE_GROUP_BOTH); |
241 gtk_size_group_add_widget(size_group, status_label_); | 297 gtk_size_group_add_widget(size_group, status_label_); |
242 gtk_size_group_add_widget(size_group, link_alignment_); | 298 gtk_size_group_add_widget(size_group, link_alignment_); |
243 g_object_unref(size_group); | 299 g_object_unref(size_group); |
244 } | 300 } |
245 | 301 |
246 gtk_box_pack_start(GTK_BOX(item_hbox), item_vbox, TRUE, TRUE, 0); | 302 gtk_box_pack_start(GTK_BOX(item_hbox), item_vbox, TRUE, TRUE, 0); |
247 gtk_container_add(GTK_CONTAINER(widget_.get()), item_hbox); | 303 gtk_container_add(GTK_CONTAINER(widget_.get()), item_hbox); |
248 } | 304 } |
OLD | NEW |