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

Side by Side Diff: chrome/browser/ui/gtk/avatar_menu_bubble_gtk.cc

Issue 231733005: Delete the GTK+ port of Chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remerge to ToT Created 6 years, 8 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
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/gtk/avatar_menu_bubble_gtk.h"
6
7 #include "base/i18n/rtl.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/profiles/avatar_menu.h"
12 #include "chrome/browser/profiles/profile_info_cache.h"
13 #include "chrome/browser/profiles/profile_manager.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/gtk/avatar_menu_item_gtk.h"
16 #include "chrome/browser/ui/gtk/browser_toolbar_gtk.h"
17 #include "chrome/browser/ui/gtk/browser_window_gtk.h"
18 #include "chrome/browser/ui/gtk/event_utils.h"
19 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h"
20 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
21 #include "chrome/browser/ui/gtk/location_bar_view_gtk.h"
22 #include "content/public/browser/notification_source.h"
23 #include "grit/generated_resources.h"
24 #include "ui/base/gtk/gtk_hig_constants.h"
25 #include "ui/base/l10n/l10n_util.h"
26
27 namespace {
28
29 // The minimum width in pixels of the bubble.
30 const int kBubbleMinWidth = 175;
31
32 // The number of pixels of padding on the left of the 'New Profile' link at the
33 // bottom of the bubble.
34 const int kNewProfileLinkLeftPadding = 40;
35
36 } // namespace
37
38 AvatarMenuBubbleGtk::AvatarMenuBubbleGtk(Browser* browser,
39 GtkWidget* anchor,
40 BubbleGtk::FrameStyle arrow,
41 const gfx::Rect* rect)
42 : contents_(NULL),
43 inner_contents_(NULL),
44 theme_service_(GtkThemeService::GetFrom(browser->profile())),
45 new_profile_link_(NULL),
46 minimum_width_(kBubbleMinWidth),
47 switching_(false) {
48 avatar_menu_.reset(new AvatarMenu(
49 &g_browser_process->profile_manager()->GetProfileInfoCache(),
50 this, browser));
51 avatar_menu_->RebuildMenu();
52
53 OnAvatarMenuChanged(avatar_menu_.get());
54
55 bubble_ = BubbleGtk::Show(anchor,
56 rect,
57 contents_,
58 arrow,
59 BubbleGtk::MATCH_SYSTEM_THEME |
60 BubbleGtk::POPUP_WINDOW |
61 BubbleGtk::GRAB_INPUT,
62 theme_service_,
63 this); // |delegate|
64 g_signal_connect(contents_, "destroy",
65 G_CALLBACK(&OnDestroyThunk), this);
66 }
67
68 AvatarMenuBubbleGtk::~AvatarMenuBubbleGtk() {}
69
70 void AvatarMenuBubbleGtk::OnDestroy(GtkWidget* widget) {
71 // We are self deleting, we have a destroy signal setup to catch when we
72 // destroyed (via the BubbleGtk being destroyed), and delete ourself.
73 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
74 }
75
76 void AvatarMenuBubbleGtk::BubbleClosing(BubbleGtk* bubble,
77 bool closed_by_escape) {
78 bubble_ = NULL;
79 }
80
81 void AvatarMenuBubbleGtk::OnAvatarMenuChanged(
82 AvatarMenu* avatar_menu) {
83 items_.clear();
84 minimum_width_ = kBubbleMinWidth;
85
86 InitContents();
87 }
88
89 void AvatarMenuBubbleGtk::OpenProfile(size_t profile_index) {
90 if (!bubble_)
91 return;
92 GdkModifierType modifier_state;
93 gtk_get_current_event_state(&modifier_state);
94 guint modifier_state_uint = modifier_state;
95 avatar_menu_->SwitchToProfile(profile_index,
96 event_utils::DispositionFromGdkState(modifier_state_uint) == NEW_WINDOW,
97 ProfileMetrics::SWITCH_PROFILE_ICON);
98 CloseBubble();
99 }
100
101 void AvatarMenuBubbleGtk::EditProfile(size_t profile_index) {
102 if (!bubble_)
103 return;
104 avatar_menu_->EditProfile(profile_index);
105 CloseBubble();
106 }
107
108 void AvatarMenuBubbleGtk::OnSizeRequest(GtkWidget* widget,
109 GtkRequisition* req) {
110 // Always use the maximum width ever requested.
111 if (req->width < minimum_width_)
112 req->width = minimum_width_;
113 else
114 minimum_width_ = req->width;
115 }
116
117 void AvatarMenuBubbleGtk::OnNewProfileLinkClicked(GtkWidget* link) {
118 if (!bubble_)
119 return;
120 avatar_menu_->AddNewProfile(ProfileMetrics::ADD_NEW_USER_ICON);
121 CloseBubble();
122 }
123
124 void AvatarMenuBubbleGtk::OnSwitchProfileLinkClicked(GtkWidget* link) {
125 switching_ = true;
126 OnAvatarMenuChanged(avatar_menu_.get());
127 }
128
129 void AvatarMenuBubbleGtk::InitMenuContents() {
130 size_t profile_count = avatar_menu_->GetNumberOfItems();
131 GtkWidget* items_vbox = gtk_vbox_new(FALSE, ui::kContentAreaSpacing);
132 for (size_t i = 0; i < profile_count; ++i) {
133 AvatarMenu::Item menu_item = avatar_menu_->GetItemAt(i);
134 AvatarMenuItemGtk* item = new AvatarMenuItemGtk(
135 this, menu_item, i, theme_service_);
136 items_.push_back(item);
137
138 gtk_box_pack_start(GTK_BOX(items_vbox), item->widget(), TRUE, TRUE, 0);
139 gtk_widget_set_can_focus(item->widget(), TRUE);
140 if (menu_item.active)
141 gtk_container_set_focus_child(GTK_CONTAINER(items_vbox), item->widget());
142 }
143 gtk_box_pack_start(GTK_BOX(inner_contents_), items_vbox, TRUE, TRUE, 0);
144
145 if (avatar_menu_->ShouldShowAddNewProfileLink()) {
146 gtk_box_pack_start(GTK_BOX(inner_contents_),
147 gtk_hseparator_new(), TRUE, TRUE, 0);
148
149 // The new profile link.
150 new_profile_link_ = theme_service_->BuildChromeLinkButton(
151 l10n_util::GetStringUTF8(IDS_PROFILES_CREATE_NEW_PROFILE_LINK));
152 g_signal_connect(new_profile_link_, "clicked",
153 G_CALLBACK(OnNewProfileLinkClickedThunk), this);
154
155 GtkWidget* link_align = gtk_alignment_new(0, 0, 0, 0);
156 gtk_alignment_set_padding(GTK_ALIGNMENT(link_align),
157 0, 0, kNewProfileLinkLeftPadding, 0);
158 gtk_container_add(GTK_CONTAINER(link_align), new_profile_link_);
159
160 gtk_box_pack_start(GTK_BOX(inner_contents_), link_align, FALSE, FALSE, 0);
161 }
162 }
163
164 void AvatarMenuBubbleGtk::InitManagedUserContents() {
165 int active_index = avatar_menu_->GetActiveProfileIndex();
166 AvatarMenu::Item menu_item =
167 avatar_menu_->GetItemAt(active_index);
168 AvatarMenuItemGtk* item = new AvatarMenuItemGtk(
169 this, menu_item, active_index, theme_service_);
170 items_.push_back(item);
171
172 gtk_box_pack_start(GTK_BOX(inner_contents_), item->widget(), TRUE, TRUE, 0);
173 gtk_box_pack_start(GTK_BOX(inner_contents_),
174 gtk_hseparator_new(), TRUE, TRUE, 0);
175
176 // Add information about managed users within a hbox.
177 GtkWidget* managed_user_info = gtk_hbox_new(FALSE, 5);
178 GdkPixbuf* limited_user_pixbuf =
179 avatar_menu_->GetManagedUserIcon().ToGdkPixbuf();
180 GtkWidget* limited_user_img = gtk_image_new_from_pixbuf(limited_user_pixbuf);
181 GtkWidget* icon_align = gtk_alignment_new(0, 0, 0, 0);
182 gtk_container_add(GTK_CONTAINER(icon_align), limited_user_img);
183 gtk_box_pack_start(GTK_BOX(managed_user_info), icon_align, FALSE, FALSE, 0);
184 GtkWidget* status_label =
185 theme_service_->BuildLabel(std::string(), ui::kGdkBlack);
186 char* markup = g_markup_printf_escaped(
187 "<span size='small'>%s</span>",
188 base::UTF16ToUTF8(avatar_menu_->GetManagedUserInformation()).c_str());
189 const int kLabelWidth = 150;
190 gtk_widget_set_size_request(status_label, kLabelWidth, -1);
191 gtk_label_set_markup(GTK_LABEL(status_label), markup);
192 gtk_label_set_line_wrap(GTK_LABEL(status_label), TRUE);
193 gtk_misc_set_alignment(GTK_MISC(status_label), 0, 0);
194 g_free(markup);
195 gtk_box_pack_start(GTK_BOX(managed_user_info), status_label, FALSE, FALSE, 0);
196 gtk_box_pack_start(
197 GTK_BOX(inner_contents_), managed_user_info, FALSE, FALSE, 0);
198
199 gtk_box_pack_start(
200 GTK_BOX(inner_contents_), gtk_hseparator_new(), TRUE, TRUE, 0);
201
202 // The switch profile link.
203 GtkWidget* switch_profile_link = theme_service_->BuildChromeLinkButton(
204 l10n_util::GetStringUTF8(IDS_PROFILES_SWITCH_PROFILE_LINK));
205 g_signal_connect(switch_profile_link, "clicked",
206 G_CALLBACK(OnSwitchProfileLinkClickedThunk), this);
207
208 GtkWidget* link_align = gtk_alignment_new(0.5, 0, 0, 0);
209 gtk_container_add(GTK_CONTAINER(link_align), switch_profile_link);
210
211 gtk_box_pack_start(GTK_BOX(inner_contents_), link_align, FALSE, FALSE, 0);
212 }
213
214 void AvatarMenuBubbleGtk::InitContents() {
215 // Destroy the old inner contents to allow replacing it.
216 if (inner_contents_)
217 gtk_widget_destroy(inner_contents_);
218 inner_contents_ = gtk_vbox_new(FALSE, ui::kControlSpacing);
219 if (!contents_)
220 contents_ = gtk_vbox_new(FALSE, 0);
221 gtk_container_set_border_width(GTK_CONTAINER(inner_contents_),
222 ui::kContentAreaBorder);
223 g_signal_connect(inner_contents_, "size-request",
224 G_CALLBACK(OnSizeRequestThunk), this);
225
226 if (avatar_menu_->GetManagedUserInformation().empty() || switching_)
227 InitMenuContents();
228 else
229 InitManagedUserContents();
230 gtk_box_pack_start(GTK_BOX(contents_), inner_contents_, TRUE, TRUE, 0);
231 if (bubble_)
232 gtk_widget_show_all(contents_);
233 }
234
235 void AvatarMenuBubbleGtk::CloseBubble() {
236 if (bubble_) {
237 bubble_->Close();
238 bubble_ = NULL;
239 }
240 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698