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

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

Issue 9148032: [Web Intents] Refactor picker to use WebIntentPickerModel. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix copyright year in w_i_b_c_unittest.mm Created 8 years, 11 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
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/gtk/web_intent_picker_gtk.h" 5 #include "chrome/browser/ui/gtk/web_intent_picker_gtk.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/utf_string_conversions.h"
11 #include "chrome/browser/favicon/favicon_service.h" 12 #include "chrome/browser/favicon/favicon_service.h"
12 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ui/browser.h" 14 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_window.h" 15 #include "chrome/browser/ui/browser_window.h"
15 #include "chrome/browser/ui/gtk/browser_toolbar_gtk.h" 16 #include "chrome/browser/ui/gtk/browser_toolbar_gtk.h"
16 #include "chrome/browser/ui/gtk/browser_window_gtk.h" 17 #include "chrome/browser/ui/gtk/browser_window_gtk.h"
17 #include "chrome/browser/ui/gtk/custom_button.h" 18 #include "chrome/browser/ui/gtk/custom_button.h"
18 #include "chrome/browser/ui/gtk/gtk_theme_service.h" 19 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
19 #include "chrome/browser/ui/gtk/gtk_util.h" 20 #include "chrome/browser/ui/gtk/gtk_util.h"
20 #include "chrome/browser/ui/gtk/location_bar_view_gtk.h" 21 #include "chrome/browser/ui/gtk/location_bar_view_gtk.h"
21 #include "chrome/browser/ui/gtk/tab_contents_container_gtk.h" 22 #include "chrome/browser/ui/gtk/tab_contents_container_gtk.h"
22 #include "chrome/browser/ui/intents/web_intent_picker_controller.h" 23 #include "chrome/browser/ui/intents/web_intent_picker_controller.h"
23 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h" 24 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h"
25 #include "chrome/browser/ui/intents/web_intent_picker_model.h"
24 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 26 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
25 #include "content/browser/renderer_host/render_view_host.h" 27 #include "content/browser/renderer_host/render_view_host.h"
26 #include "content/browser/renderer_host/render_widget_host_view_gtk.h" 28 #include "content/browser/renderer_host/render_widget_host_view_gtk.h"
27 #include "content/public/browser/notification_registrar.h" 29 #include "content/public/browser/notification_registrar.h"
28 #include "content/public/browser/notification_source.h" 30 #include "content/public/browser/notification_source.h"
29 #include "content/public/browser/notification_types.h" 31 #include "content/public/browser/notification_types.h"
30 #include "content/public/browser/web_contents.h" 32 #include "content/public/browser/web_contents.h"
31 #include "content/public/browser/web_contents_view.h" 33 #include "content/public/browser/web_contents_view.h"
32 #include "googleurl/src/gurl.h" 34 #include "googleurl/src/gurl.h"
33 #include "grit/generated_resources.h" 35 #include "grit/generated_resources.h"
34 #include "grit/theme_resources.h"
35 #include "grit/theme_resources_standard.h"
36 #include "grit/ui_resources.h"
37 #include "ui/base/gtk/gtk_hig_constants.h" 36 #include "ui/base/gtk/gtk_hig_constants.h"
38 #include "ui/base/l10n/l10n_util.h" 37 #include "ui/base/l10n/l10n_util.h"
39 #include "ui/base/resource/resource_bundle.h" 38 #include "ui/base/resource/resource_bundle.h"
40 #include "ui/gfx/gtk_util.h" 39 #include "ui/gfx/gtk_util.h"
41 #include "ui/gfx/image/image.h" 40 #include "ui/gfx/image/image.h"
42 41
43 using content::WebContents; 42 using content::WebContents;
44 43
45 namespace { 44 namespace {
46 45
47 // The width in pixels of the area between the icon on the left and the close 46 // The width in pixels of the area between the icon on the left and the close
48 // button on the right. 47 // button on the right.
49 const int kMainContentWidth = 300; 48 const int kMainContentWidth = 300;
50 49
51 // The length in pixels of the label at the bottom of the picker. Text longer 50 // The length in pixels of the label at the bottom of the picker. Text longer
52 // than this width will wrap. 51 // than this width will wrap.
53 const int kWebStoreLabelLength = 300; 52 const int kWebStoreLabelLength = 300;
54 53
55 // The pixel size of the label at the bottom of the picker. 54 // The pixel size of the label at the bottom of the picker.
56 const int kWebStoreLabelPixelSize = 11; 55 const int kWebStoreLabelPixelSize = 11;
57 56
58 // How much to scale the the buttons up from their favicon size.
59 const int kServiceButtonScale = 3;
60
61 GtkThemeService *GetThemeService(TabContentsWrapper* wrapper) { 57 GtkThemeService *GetThemeService(TabContentsWrapper* wrapper) {
62 return GtkThemeService::GetFrom(wrapper->profile()); 58 return GtkThemeService::GetFrom(wrapper->profile());
63 } 59 }
64 60
65 // Set the image of |button| to |pixbuf|, and scale the button up by 61 // Set the image of |button| to |pixbuf|, and scale the button up by
66 // |kServiceButtonScale|. 62 // |kServiceButtonScale|.
67 void SetServiceButtonImage(GtkWidget* button, GdkPixbuf* pixbuf) { 63 void SetServiceButtonImage(GtkWidget* button, GdkPixbuf* pixbuf) {
68 int width = gdk_pixbuf_get_width(pixbuf); 64 gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_pixbuf(pixbuf));
69 int height = gdk_pixbuf_get_height(pixbuf); 65 gtk_button_set_image_position(GTK_BUTTON(button), GTK_POS_LEFT);
70 gtk_button_set_image(GTK_BUTTON(button), 66 }
71 gtk_image_new_from_pixbuf(pixbuf)); 67
72 gtk_widget_set_size_request(button, 68 // This helper function removes a widget from its parent container widget.
73 width * kServiceButtonScale, 69 void RemoveAllHelper(GtkWidget* widget, gpointer data) {
74 height * kServiceButtonScale); 70 GtkWidget* parent = gtk_widget_get_parent(widget);
71 gtk_container_remove(GTK_CONTAINER(parent), widget);
75 } 72 }
76 73
77 } // namespace 74 } // namespace
78 75
79 // static 76 // static
80 WebIntentPicker* WebIntentPicker::Create(Browser* browser, 77 WebIntentPicker* WebIntentPicker::Create(Browser* browser,
81 TabContentsWrapper* wrapper, 78 TabContentsWrapper* wrapper,
82 WebIntentPickerDelegate* delegate) { 79 WebIntentPickerDelegate* delegate,
83 return new WebIntentPickerGtk(browser, wrapper, delegate); 80 WebIntentPickerModel* model) {
81 return new WebIntentPickerGtk(browser, wrapper, delegate, model);
84 } 82 }
85 83
86 WebIntentPickerGtk::WebIntentPickerGtk(Browser* browser, 84 WebIntentPickerGtk::WebIntentPickerGtk(Browser* browser,
87 TabContentsWrapper* wrapper, 85 TabContentsWrapper* wrapper,
88 WebIntentPickerDelegate* delegate) 86 WebIntentPickerDelegate* delegate,
87 WebIntentPickerModel* model)
89 : wrapper_(wrapper), 88 : wrapper_(wrapper),
90 delegate_(delegate), 89 delegate_(delegate),
90 model_(model),
91 contents_(NULL), 91 contents_(NULL),
92 button_hbox_(NULL), 92 button_vbox_(NULL),
93 bubble_(NULL), 93 bubble_(NULL),
94 browser_(browser) { 94 browser_(browser) {
95 DCHECK(delegate_ != NULL); 95 DCHECK(delegate_ != NULL);
96 DCHECK(browser); 96 DCHECK(browser);
97 DCHECK(browser->window()); 97 DCHECK(browser->window());
98
99 model_->set_observer(this);
100
98 BrowserWindowGtk* browser_window = 101 BrowserWindowGtk* browser_window =
99 BrowserWindowGtk::GetBrowserWindowForNativeWindow( 102 BrowserWindowGtk::GetBrowserWindowForNativeWindow(
100 browser->window()->GetNativeHandle()); 103 browser->window()->GetNativeHandle());
101 104
102 GtkWidget* anchor = browser_window-> 105 GtkWidget* anchor = browser_window->
103 GetToolbar()->GetLocationBarView()->location_icon_widget(); 106 GetToolbar()->GetLocationBarView()->location_icon_widget();
104 107
105 InitContents(); 108 InitContents();
106 109
107 BubbleGtk::ArrowLocationGtk arrow_location = base::i18n::IsRTL() ? 110 BubbleGtk::ArrowLocationGtk arrow_location = base::i18n::IsRTL() ?
108 BubbleGtk::ARROW_LOCATION_TOP_RIGHT : 111 BubbleGtk::ARROW_LOCATION_TOP_RIGHT :
109 BubbleGtk::ARROW_LOCATION_TOP_LEFT; 112 BubbleGtk::ARROW_LOCATION_TOP_LEFT;
110 bubble_ = BubbleGtk::Show(anchor, 113 bubble_ = BubbleGtk::Show(anchor,
111 NULL, // |rect| 114 NULL, // |rect|
112 contents_, 115 contents_,
113 arrow_location, 116 arrow_location,
114 true, // |match_system_theme| 117 true, // |match_system_theme|
115 true, // |grab_input| 118 true, // |grab_input|
116 GetThemeService(wrapper), 119 GetThemeService(wrapper),
117 this); // |delegate| 120 this); // |delegate|
118 } 121 }
119 122
120 WebIntentPickerGtk::~WebIntentPickerGtk() { 123 WebIntentPickerGtk::~WebIntentPickerGtk() {
121 DCHECK(bubble_ == NULL) << "Should have closed window before destroying."; 124 DCHECK(bubble_ == NULL) << "Should have closed window before destroying.";
122 } 125 }
123 126
124 void WebIntentPickerGtk::SetServiceURLs(const std::vector<GURL>& urls) { 127 void WebIntentPickerGtk::OnModelChanged(WebIntentPickerModel* model) {
125 for (size_t i = 0; i < urls.size(); ++i) { 128 RemoveAllFrom(button_vbox_);
129
130 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
131
132 for (size_t i = 0; i < model->GetItemCount(); ++i) {
133 const WebIntentPickerModel::Item& item = model->GetItemAt(i);
134
126 GtkWidget* button = gtk_button_new(); 135 GtkWidget* button = gtk_button_new();
127 gtk_widget_set_tooltip_text(button, urls[i].spec().c_str()); 136
128 gtk_box_pack_start(GTK_BOX(button_hbox_), button, FALSE, FALSE, 0); 137 gtk_widget_set_tooltip_text(button, item.url.spec().c_str());
138 gtk_button_set_label(GTK_BUTTON(button), UTF16ToUTF8(item.title).c_str());
139
140 gtk_box_pack_start(GTK_BOX(button_vbox_), button, FALSE, FALSE, 0);
129 g_signal_connect(button, 141 g_signal_connect(button,
130 "clicked", 142 "clicked",
131 G_CALLBACK(OnServiceButtonClickThunk), 143 G_CALLBACK(OnServiceButtonClickThunk),
132 this); 144 this);
145
146 SetServiceButtonImage(button, item.favicon.ToGdkPixbuf());
133 } 147 }
134 148
135 // Add the '+' button, to use the Chrome Web Store. 149 gtk_widget_show_all(button_vbox_);
136 GtkWidget* plus_button = gtk_button_new();
137 gtk_widget_set_tooltip_text(
138 plus_button,
139 l10n_util::GetStringUTF8(IDS_FIND_MORE_INTENT_HANDLER_TOOLTIP).c_str());
140 gtk_box_pack_start(GTK_BOX(button_hbox_), plus_button, FALSE, FALSE, 0);
141
142 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
143 GdkPixbuf* icon_pixbuf = rb.GetNativeImageNamed(IDR_SIDETABS_NEW_TAB);
144 SetServiceButtonImage(plus_button, icon_pixbuf);
145
146 gtk_widget_show_all(button_hbox_);
147 } 150 }
148 151
149 void WebIntentPickerGtk::SetServiceIcon(size_t index, const SkBitmap& icon) { 152 void WebIntentPickerGtk::OnFaviconChanged(WebIntentPickerModel* model,
150 if (icon.empty()) 153 size_t index) {
151 return; 154 const WebIntentPickerModel::Item& item = model->GetItemAt(index);
152
153 GtkWidget* button = GetServiceButton(index); 155 GtkWidget* button = GetServiceButton(index);
154 156 SetServiceButtonImage(button, item.favicon.ToGdkPixbuf());
155 GdkPixbuf* icon_pixbuf = gfx::GdkPixbufFromSkBitmap(&icon);
156 SetServiceButtonImage(button, icon_pixbuf);
157 g_object_unref(icon_pixbuf);
158 } 157 }
159 158
160 void WebIntentPickerGtk::SetDefaultServiceIcon(size_t index) { 159 void WebIntentPickerGtk::OnInlineDisposition(WebIntentPickerModel* model) {
161 GtkWidget* button = GetServiceButton(index); 160 const WebIntentPickerModel::Item& item = model->GetItemAt(
161 model->inline_disposition_index());
162 const GURL& url = item.url;
162 163
163 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 164 content::WebContents* web_contents = content::WebContents::Create(
164 GdkPixbuf* icon_pixbuf = rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON); 165 browser_->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL);
165 SetServiceButtonImage(button, icon_pixbuf); 166 inline_disposition_tab_contents_.reset(new TabContentsWrapper(web_contents));
167 inline_disposition_delegate_.reset(new InlineDispositionDelegate);
168 web_contents->SetDelegate(inline_disposition_delegate_.get());
169 tab_contents_container_.reset(new TabContentsContainerGtk(NULL));
170 tab_contents_container_->SetTab(inline_disposition_tab_contents_.get());
171
172 inline_disposition_tab_contents_->web_contents()->GetController().LoadURL(
173 url, content::Referrer(), content::PAGE_TRANSITION_START_PAGE,
174 std::string());
175
176 // Replace the bubble picker contents with the inline disposition.
177
178 RemoveAllFrom(contents_);
179
180 GtkWidget* service_hbox = gtk_hbox_new(FALSE, ui::kControlSpacing);
181 // TODO(gbillock): Eventually get the service icon button here.
182 // Maybe add a title or something too?
183 close_button_.reset(
184 CustomDrawButton::CloseButton(GetThemeService(wrapper_)));
185 g_signal_connect(close_button_->widget(),
186 "clicked",
187 G_CALLBACK(OnCloseButtonClickThunk),
188 this);
189 gtk_widget_set_can_focus(close_button_->widget(), FALSE);
190 GtkWidget* close_vbox = gtk_vbox_new(FALSE, 0);
191 gtk_box_pack_start(GTK_BOX(close_vbox), close_button_->widget(),
192 FALSE, FALSE, 0);
193 gtk_box_pack_end(GTK_BOX(service_hbox), close_vbox, FALSE, FALSE, 0);
194
195 GtkWidget* vbox = gtk_vbox_new(FALSE, ui::kContentAreaSpacing);
196 gtk_box_pack_start(GTK_BOX(vbox), service_hbox, TRUE, TRUE, 0);
197
198 // The separator between the icon/title/close and the inline renderer.
199 gtk_box_pack_start(GTK_BOX(vbox), gtk_hseparator_new(), FALSE, TRUE, 0);
200
201 gtk_box_pack_end(GTK_BOX(vbox), tab_contents_container_->widget(),
202 TRUE, TRUE, 0);
203
204 gtk_container_add(GTK_CONTAINER(contents_), vbox);
205
206 // TODO(gbillock): This size calculation needs more thought.
207 // Move up to WebIntentPicker?
208 gfx::Size tab_size = wrapper_->web_contents()->GetView()->GetContainerSize();
209 int width = std::max(tab_size.width()/2, kMainContentWidth);
210 int height = std::max(tab_size.height()/2, kMainContentWidth);
211 gtk_widget_set_size_request(tab_contents_container_->widget(),
212 width, height);
213 gtk_widget_show_all(contents_);
214
215 delegate_->OnInlineDispositionWebContentsCreated(web_contents);
166 } 216 }
167 217
168 void WebIntentPickerGtk::Close() { 218 void WebIntentPickerGtk::Close() {
169 bubble_->Close(); 219 bubble_->Close();
170 bubble_ = NULL;
171 if (inline_disposition_tab_contents_.get()) 220 if (inline_disposition_tab_contents_.get())
172 inline_disposition_tab_contents_->web_contents()->OnCloseStarted(); 221 inline_disposition_tab_contents_->web_contents()->OnCloseStarted();
173 } 222 }
174 223
175 void WebIntentPickerGtk::BubbleClosing(BubbleGtk* bubble, 224 void WebIntentPickerGtk::BubbleClosing(BubbleGtk* bubble,
176 bool closed_by_escape) { 225 bool closed_by_escape) {
177 delegate_->OnClosing(); 226 delegate_->OnClosing();
178 } 227 }
179 228
180 void WebIntentPickerGtk::OnCloseButtonClick(GtkWidget* button) { 229 void WebIntentPickerGtk::OnCloseButtonClick(GtkWidget* button) {
181 delegate_->OnCancelled(); 230 delegate_->OnCancelled();
182 delegate_->OnClosing(); 231 delegate_->OnClosing();
183 } 232 }
184 233
234 void WebIntentPickerGtk::OnDestroy(GtkWidget* button) {
235 // Destroy this object when the BubbleGtk is destroyed. It can't be "delete
236 // this" because this function happens in a callback.
237 MessageLoop::current()->DeleteSoon(FROM_HERE, this);
238 model_->set_observer(NULL);
239 bubble_ = NULL;
240 }
241
185 void WebIntentPickerGtk::OnServiceButtonClick(GtkWidget* button) { 242 void WebIntentPickerGtk::OnServiceButtonClick(GtkWidget* button) {
186 GList* button_list = gtk_container_get_children(GTK_CONTAINER(button_hbox_)); 243 GList* button_list = gtk_container_get_children(GTK_CONTAINER(button_vbox_));
187 gint index = g_list_index(button_list, button); 244 gint index = g_list_index(button_list, button);
188 DCHECK(index != -1); 245 DCHECK(index != -1);
189 246
190 delegate_->OnServiceChosen(static_cast<size_t>(index)); 247 const WebIntentPickerModel::Item& item = model_->GetItemAt(index);
248
249 delegate_->OnServiceChosen(static_cast<size_t>(index), item.disposition);
191 } 250 }
192 251
193 void WebIntentPickerGtk::InitContents() { 252 void WebIntentPickerGtk::InitContents() {
194 GtkThemeService* theme_service = GetThemeService(wrapper_); 253 GtkThemeService* theme_service = GetThemeService(wrapper_);
195 254
196 contents_ = gtk_hbox_new(FALSE, ui::kContentAreaSpacing); 255 contents_ = gtk_hbox_new(FALSE, ui::kContentAreaSpacing);
197 gtk_container_set_border_width(GTK_CONTAINER(contents_), 256 gtk_container_set_border_width(GTK_CONTAINER(contents_),
198 ui::kContentAreaBorder); 257 ui::kContentAreaBorder);
199 258
200 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
201 GdkPixbuf* image_pixbuf = rb.GetNativeImageNamed(IDR_PAGEINFO_INFO);
202 GtkWidget* image = gtk_image_new_from_pixbuf(image_pixbuf);
203 gtk_box_pack_start(GTK_BOX(contents_), image, FALSE, FALSE, 0);
204 gtk_misc_set_alignment(GTK_MISC(image), 0, 0);
205
206 GtkWidget* vbox = gtk_vbox_new(FALSE, ui::kContentAreaSpacing); 259 GtkWidget* vbox = gtk_vbox_new(FALSE, ui::kContentAreaSpacing);
207 260
208 GtkWidget* label = theme_service->BuildLabel( 261 GtkWidget* label = theme_service->BuildLabel(
209 l10n_util::GetStringUTF8(IDS_CHOOSE_INTENT_HANDLER_MESSAGE).c_str(), 262 l10n_util::GetStringUTF8(IDS_CHOOSE_INTENT_HANDLER_MESSAGE).c_str(),
210 ui::kGdkBlack); 263 ui::kGdkBlack);
211 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); 264 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
212 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 265 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
213 266
214 gtk_widget_set_size_request(vbox, kMainContentWidth, -1); 267 gtk_widget_set_size_request(vbox, kMainContentWidth, -1);
215 268
216 button_hbox_ = gtk_hbox_new(FALSE, ui::kControlSpacing); 269 button_vbox_ = gtk_vbox_new(FALSE, ui::kControlSpacing);
217 gtk_box_pack_start(GTK_BOX(vbox), button_hbox_, TRUE, TRUE, 0); 270 gtk_box_pack_start(GTK_BOX(vbox), button_vbox_, TRUE, TRUE, 0);
218 271
219 GtkWidget* cws_label = theme_service->BuildLabel( 272 GtkWidget* cws_label = theme_service->BuildLabel(
220 l10n_util::GetStringUTF8(IDS_FIND_MORE_INTENT_HANDLER_MESSAGE).c_str(), 273 l10n_util::GetStringUTF8(IDS_FIND_MORE_INTENT_HANDLER_MESSAGE).c_str(),
221 ui::kGdkBlack); 274 ui::kGdkBlack);
222 gtk_box_pack_start(GTK_BOX(vbox), cws_label, TRUE, TRUE, 0); 275 gtk_box_pack_start(GTK_BOX(vbox), cws_label, TRUE, TRUE, 0);
223 gtk_misc_set_alignment(GTK_MISC(cws_label), 0, 0); 276 gtk_misc_set_alignment(GTK_MISC(cws_label), 0, 0);
224 gtk_util::SetLabelWidth(cws_label, kWebStoreLabelLength); 277 gtk_util::SetLabelWidth(cws_label, kWebStoreLabelLength);
225 gtk_util::ForceFontSizePixels(cws_label, kWebStoreLabelPixelSize); 278 gtk_util::ForceFontSizePixels(cws_label, kWebStoreLabelPixelSize);
226 279
227 gtk_box_pack_start(GTK_BOX(contents_), vbox, TRUE, TRUE, 0); 280 gtk_box_pack_start(GTK_BOX(contents_), vbox, TRUE, TRUE, 0);
228 281
229 close_button_.reset( 282 close_button_.reset(
230 CustomDrawButton::CloseButton(GetThemeService(wrapper_))); 283 CustomDrawButton::CloseButton(GetThemeService(wrapper_)));
231 g_signal_connect(close_button_->widget(), 284 g_signal_connect(close_button_->widget(),
232 "clicked", 285 "clicked",
233 G_CALLBACK(OnCloseButtonClickThunk), 286 G_CALLBACK(OnCloseButtonClickThunk),
234 this); 287 this);
235 gtk_widget_set_can_focus(close_button_->widget(), FALSE); 288 gtk_widget_set_can_focus(close_button_->widget(), FALSE);
236 289
237 GtkWidget* close_vbox = gtk_vbox_new(FALSE, 0); 290 GtkWidget* close_vbox = gtk_vbox_new(FALSE, 0);
238 gtk_box_pack_start(GTK_BOX(close_vbox), close_button_->widget(), FALSE, FALSE, 291 gtk_box_pack_start(GTK_BOX(close_vbox), close_button_->widget(), FALSE, FALSE,
239 0); 292 0);
240 gtk_box_pack_end(GTK_BOX(contents_), close_vbox, FALSE, FALSE, 0); 293 gtk_box_pack_end(GTK_BOX(contents_), close_vbox, FALSE, FALSE, 0);
241 } 294 g_signal_connect(contents_, "destroy", G_CALLBACK(&OnDestroyThunk), this);
242
243 void RemoveAllHelper(GtkWidget* widget, gpointer data) {
244 GtkWidget* parent = gtk_widget_get_parent(widget);
245 gtk_container_remove(GTK_CONTAINER(parent), widget);
246 }
247
248 WebContents* WebIntentPickerGtk::SetInlineDisposition(const GURL& url) {
249 WebContents* web_contents = WebContents::Create(
250 browser_->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL);
251 inline_disposition_tab_contents_.reset(new TabContentsWrapper(web_contents));
252 inline_disposition_delegate_.reset(new InlineDispositionDelegate);
253 web_contents->SetDelegate(inline_disposition_delegate_.get());
254 tab_contents_container_.reset(new TabContentsContainerGtk(NULL));
255 tab_contents_container_->SetTab(inline_disposition_tab_contents_.get());
256
257 inline_disposition_tab_contents_->web_contents()->GetController().LoadURL(
258 url, content::Referrer(), content::PAGE_TRANSITION_START_PAGE,
259 std::string());
260
261 // Replace the bubble picker contents with the inline disposition.
262
263 gtk_container_foreach(GTK_CONTAINER(contents_), RemoveAllHelper, NULL);
264
265 GtkWidget* service_hbox = gtk_hbox_new(FALSE, ui::kControlSpacing);
266 // TODO(gbillock): Eventually get the service icon button here.
267 // Maybe add a title or something too?
268 close_button_.reset(
269 CustomDrawButton::CloseButton(GetThemeService(wrapper_)));
270 g_signal_connect(close_button_->widget(),
271 "clicked",
272 G_CALLBACK(OnCloseButtonClickThunk),
273 this);
274 gtk_widget_set_can_focus(close_button_->widget(), FALSE);
275 GtkWidget* close_vbox = gtk_vbox_new(FALSE, 0);
276 gtk_box_pack_start(GTK_BOX(close_vbox), close_button_->widget(),
277 FALSE, FALSE, 0);
278 gtk_box_pack_end(GTK_BOX(service_hbox), close_vbox, FALSE, FALSE, 0);
279
280 GtkWidget* vbox = gtk_vbox_new(FALSE, ui::kContentAreaSpacing);
281 gtk_box_pack_start(GTK_BOX(vbox), service_hbox, TRUE, TRUE, 0);
282
283 // The separator between the icon/title/close and the inline renderer.
284 gtk_box_pack_start(GTK_BOX(vbox), gtk_hseparator_new(), FALSE, TRUE, 0);
285
286 gtk_box_pack_end(GTK_BOX(vbox), tab_contents_container_->widget(),
287 TRUE, TRUE, 0);
288
289 gtk_container_add(GTK_CONTAINER(contents_), vbox);
290
291 // TODO(gbillock): This size calculation needs more thought.
292 // Move up to WebIntentPicker?
293 gfx::Size tab_size = wrapper_->web_contents()->GetView()->GetContainerSize();
294 int width = std::max(tab_size.width()/2, kMainContentWidth);
295 int height = std::max(tab_size.height()/2, kMainContentWidth);
296 gtk_widget_set_size_request(tab_contents_container_->widget(),
297 width, height);
298 gtk_widget_show_all(contents_);
299
300 return inline_disposition_tab_contents_->web_contents();
301 } 295 }
302 296
303 GtkWidget* WebIntentPickerGtk::GetServiceButton(size_t index) { 297 GtkWidget* WebIntentPickerGtk::GetServiceButton(size_t index) {
304 GList* button_list = gtk_container_get_children(GTK_CONTAINER(button_hbox_)); 298 GList* button_list = gtk_container_get_children(GTK_CONTAINER(button_vbox_));
305 GtkWidget* button = GTK_WIDGET(g_list_nth_data(button_list, index)); 299 GtkWidget* button = GTK_WIDGET(g_list_nth_data(button_list, index));
306 DCHECK(button != NULL); 300 DCHECK(button != NULL);
307 301
308 return button; 302 return button;
309 } 303 }
310 304
305 void WebIntentPickerGtk::RemoveAllFrom(GtkWidget* container) {
306 gtk_container_foreach(GTK_CONTAINER(container), RemoveAllHelper, NULL);
Elliot Glaysher 2012/01/27 18:30:18 gtk_util::RemoveAllChildren(). declared in chrome/
binji 2012/01/27 19:04:20 Done.
307 }
308
311 // WebIntentPickerGtk::InlineDispositionDelegate 309 // WebIntentPickerGtk::InlineDispositionDelegate
312 310
313 WebIntentPickerGtk::InlineDispositionDelegate::InlineDispositionDelegate() {} 311 WebIntentPickerGtk::InlineDispositionDelegate::InlineDispositionDelegate() {}
314 WebIntentPickerGtk::InlineDispositionDelegate::~InlineDispositionDelegate() {} 312 WebIntentPickerGtk::InlineDispositionDelegate::~InlineDispositionDelegate() {}
315 313
316
317 bool WebIntentPickerGtk::InlineDispositionDelegate::IsPopupOrPanel( 314 bool WebIntentPickerGtk::InlineDispositionDelegate::IsPopupOrPanel(
318 const WebContents* source) const { 315 const WebContents* source) const {
319 return true; 316 return true;
320 } 317 }
321 318
322 bool WebIntentPickerGtk::InlineDispositionDelegate:: 319 bool WebIntentPickerGtk::InlineDispositionDelegate::
323 ShouldAddNavigationToHistory( 320 ShouldAddNavigationToHistory(
324 const history::HistoryAddPageArgs& add_page_args, 321 const history::HistoryAddPageArgs& add_page_args,
325 content::NavigationType navigation_type) { 322 content::NavigationType navigation_type) {
326 return false; 323 return false;
327 } 324 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698