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 <algorithm> | 5 #include <algorithm> |
6 #include <vector> | 6 #include <vector> |
7 | 7 |
8 #include "base/time.h" | |
8 #include "base/memory/scoped_vector.h" | 9 #include "base/memory/scoped_vector.h" |
9 #include "chrome/browser/ui/browser.h" | 10 #include "chrome/browser/ui/browser.h" |
10 #include "chrome/browser/ui/browser_navigator.h" | 11 #include "chrome/browser/ui/browser_navigator.h" |
11 #include "chrome/browser/ui/intents/web_intent_inline_disposition_delegate.h" | 12 #include "chrome/browser/ui/intents/web_intent_inline_disposition_delegate.h" |
12 #include "chrome/browser/ui/intents/web_intent_picker.h" | 13 #include "chrome/browser/ui/intents/web_intent_picker.h" |
13 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h" | 14 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h" |
14 #include "chrome/browser/ui/intents/web_intent_picker_model.h" | 15 #include "chrome/browser/ui/intents/web_intent_picker_model.h" |
15 #include "chrome/browser/ui/intents/web_intent_picker_model_observer.h" | 16 #include "chrome/browser/ui/intents/web_intent_picker_model_observer.h" |
16 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 17 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
17 #include "chrome/browser/ui/views/constrained_window_views.h" | 18 #include "chrome/browser/ui/views/constrained_window_views.h" |
18 #include "chrome/browser/ui/views/frame/browser_view.h" | 19 #include "chrome/browser/ui/views/frame/browser_view.h" |
19 #include "chrome/browser/ui/views/location_bar/location_icon_view.h" | 20 #include "chrome/browser/ui/views/location_bar/location_icon_view.h" |
20 #include "chrome/browser/ui/views/tab_contents/tab_contents_container.h" | 21 #include "chrome/browser/ui/views/tab_contents/tab_contents_container.h" |
21 #include "chrome/browser/ui/views/toolbar_view.h" | 22 #include "chrome/browser/ui/views/toolbar_view.h" |
22 #include "chrome/browser/ui/views/window.h" | 23 #include "chrome/browser/ui/views/window.h" |
23 #include "chrome/common/extensions/extension_constants.h" | 24 #include "chrome/common/extensions/extension_constants.h" |
24 #include "content/public/browser/web_contents.h" | 25 #include "content/public/browser/web_contents.h" |
25 #include "content/public/browser/web_contents_view.h" | 26 #include "content/public/browser/web_contents_view.h" |
26 #include "grit/chromium_strings.h" | 27 #include "grit/chromium_strings.h" |
27 #include "grit/generated_resources.h" | 28 #include "grit/generated_resources.h" |
28 #include "grit/google_chrome_strings.h" | 29 #include "grit/google_chrome_strings.h" |
29 #include "grit/theme_resources.h" | 30 #include "grit/theme_resources.h" |
31 #include "grit/ui_resources.h" | |
30 #include "grit/ui_resources_standard.h" | 32 #include "grit/ui_resources_standard.h" |
31 #include "third_party/skia/include/core/SkColor.h" | 33 #include "third_party/skia/include/core/SkColor.h" |
32 #include "ui/base/l10n/l10n_util.h" | 34 #include "ui/base/l10n/l10n_util.h" |
33 #include "ui/base/resource/resource_bundle.h" | 35 #include "ui/base/resource/resource_bundle.h" |
34 #include "ui/base/text/text_elider.h" | 36 #include "ui/base/text/text_elider.h" |
35 #include "ui/gfx/canvas.h" | 37 #include "ui/gfx/canvas.h" |
36 #include "ui/gfx/image/image.h" | 38 #include "ui/gfx/image/image.h" |
37 #include "ui/views/border.h" | 39 #include "ui/views/border.h" |
38 #include "ui/views/controls/button/image_button.h" | 40 #include "ui/views/controls/button/image_button.h" |
39 #include "ui/views/controls/button/text_button.h" | 41 #include "ui/views/controls/button/text_button.h" |
(...skipping 29 matching lines...) Expand all Loading... | |
69 | 71 |
70 // The maximum width in pixels of a suggested extension's title link. | 72 // The maximum width in pixels of a suggested extension's title link. |
71 const int kTitleLinkMaxWidth = 130; | 73 const int kTitleLinkMaxWidth = 130; |
72 | 74 |
73 // The color used to dim disabled elements. | 75 // The color used to dim disabled elements. |
74 const SkColor kHalfOpacityWhite = SkColorSetARGB(128, 255, 255, 255); | 76 const SkColor kHalfOpacityWhite = SkColorSetARGB(128, 255, 255, 255); |
75 | 77 |
76 // The color used to display a disabled link. | 78 // The color used to display a disabled link. |
77 const SkColor kDisabledLinkColor = SkColorSetRGB(128, 128, 128); | 79 const SkColor kDisabledLinkColor = SkColorSetRGB(128, 128, 128); |
78 | 80 |
81 // The time between successive throbber frames in milliseconds. | |
82 const int kThrobberFrameTimeMs = 60; | |
83 | |
79 // Enables or disables all child views of |view|. | 84 // Enables or disables all child views of |view|. |
80 void EnableChildViews(views::View* view, bool enabled) { | 85 void EnableChildViews(views::View* view, bool enabled) { |
81 for (int i = 0; i < view->child_count(); ++i) { | 86 for (int i = 0; i < view->child_count(); ++i) { |
82 views::View* child = view->child_at(i); | 87 views::View* child = view->child_at(i); |
83 child->SetEnabled(enabled); | 88 child->SetEnabled(enabled); |
84 } | 89 } |
85 } | 90 } |
86 | 91 |
87 // StarsView ------------------------------------------------------------------- | 92 // StarsView ------------------------------------------------------------------- |
88 | 93 |
(...skipping 29 matching lines...) Expand all Loading... | |
118 // TODO(binji): Add tooltip with text rating | 123 // TODO(binji): Add tooltip with text rating |
119 // "Average Rating: X.XX stars (YYYYY)" | 124 // "Average Rating: X.XX stars (YYYYY)" |
120 // Y = "1: Hated it, 2: Disliked it, 3: It was okay, 4: Liked it, | 125 // Y = "1: Hated it, 2: Disliked it, 3: It was okay, 4: Liked it, |
121 // 5: Loved it" | 126 // 5: Loved it" |
122 // Choose Y based on rounded X. | 127 // Choose Y based on rounded X. |
123 } | 128 } |
124 | 129 |
125 StarsView::~StarsView() { | 130 StarsView::~StarsView() { |
126 } | 131 } |
127 | 132 |
133 // ThrobberNativeTextButton ---------------------------------------------------- | |
134 | |
135 // A native text button that can display a throbber in place of its icon. Much | |
136 // of the logic of this class is copied from ui/views/controls/throbber.h. | |
137 class ThrobberNativeTextButton : public views::NativeTextButton { | |
138 public: | |
139 ThrobberNativeTextButton(views::ButtonListener* listener, | |
140 const string16& text); | |
141 ~ThrobberNativeTextButton(); | |
sky
2012/04/13 21:36:16
virtual
binji
2012/04/13 22:27:33
Done.
| |
142 | |
143 // Start or stop the throbber. | |
144 void StartThrobber(); | |
145 void StopThrobber(); | |
146 | |
147 // Set the throbber bitmap to use. IDR_THROBBER is used by default. | |
148 void SetFrames(const SkBitmap* frames); | |
149 | |
150 protected: | |
151 virtual const SkBitmap& GetImageToPaint() const OVERRIDE; | |
152 | |
153 private: | |
154 // The timer callback to schedule painting this view. | |
155 void Run(); | |
156 | |
157 // Bitmap that contains the throbber frames. | |
158 const SkBitmap* frames_; | |
159 | |
160 // The currently displayed frame, given to GetImageToPaint. | |
161 mutable SkBitmap this_frame_; | |
162 | |
163 // How long one frame is displayed. | |
164 base::TimeDelta frame_time_; | |
165 | |
166 // Used to schedule Run calls. | |
167 base::RepeatingTimer<ThrobberNativeTextButton> timer_; | |
168 | |
169 // How many frames we have. | |
170 int frame_count_; | |
171 | |
172 // Time when StartThrobber was called. | |
173 base::Time start_time_; | |
sky
2012/04/13 21:36:16
Use TimeTicks.
binji
2012/04/13 22:27:33
Done.
| |
174 | |
175 // Whether the throbber is shown an animating. | |
176 bool running_; | |
177 }; | |
sky
2012/04/13 21:36:16
DISALLOW_
binji
2012/04/13 22:27:33
Done.
| |
178 | |
179 ThrobberNativeTextButton::ThrobberNativeTextButton( | |
180 views::ButtonListener* listener, const string16& text) | |
181 : NativeTextButton(listener, text), | |
182 frame_time_(base::TimeDelta::FromMilliseconds(kThrobberFrameTimeMs)), | |
183 frame_count_(0), | |
184 running_(false) { | |
185 SetFrames(ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
186 IDR_THROBBER).ToSkBitmap()); | |
187 } | |
188 | |
189 ThrobberNativeTextButton::~ThrobberNativeTextButton() { | |
190 StopThrobber(); | |
191 } | |
192 | |
193 void ThrobberNativeTextButton::StartThrobber() { | |
194 if (running_) | |
195 return; | |
196 | |
197 start_time_ = base::Time::Now(); | |
198 timer_.Start(FROM_HERE, frame_time_ - base::TimeDelta::FromMilliseconds(10), | |
sky
2012/04/13 21:36:16
Why the -10ms here?
binji
2012/04/13 22:27:33
Not sure, this was copy/paste from views/controls/
| |
199 this, &ThrobberNativeTextButton::Run); | |
200 running_ = true; | |
201 | |
202 SchedulePaint(); | |
203 } | |
204 | |
205 void ThrobberNativeTextButton::StopThrobber() { | |
206 if (!running_) | |
207 return; | |
208 | |
209 timer_.Stop(); | |
210 running_ = false; | |
211 } | |
212 | |
213 void ThrobberNativeTextButton::SetFrames(const SkBitmap* frames) { | |
214 frames_ = frames; | |
215 DCHECK(frames_->width() > 0 && frames_->height() > 0); | |
216 DCHECK(frames_->width() % frames_->height() == 0); | |
217 frame_count_ = frames_->width() / frames_->height(); | |
218 PreferredSizeChanged(); | |
219 } | |
220 | |
221 const SkBitmap& ThrobberNativeTextButton::GetImageToPaint() const { | |
222 if (!running_) | |
223 return NativeTextButton::GetImageToPaint(); | |
224 | |
225 const base::TimeDelta elapsed_time = base::Time::Now() - start_time_; | |
226 const int current_frame = | |
227 static_cast<int>(elapsed_time / frame_time_) % frame_count_; | |
sky
2012/04/13 21:36:16
nit: indent 4
binji
2012/04/13 22:27:33
Done.
| |
228 const int image_size = frames_->height(); | |
229 const int image_offset = current_frame * image_size; | |
230 | |
231 SkIRect subset_rect = SkIRect::MakeXYWH(image_offset, 0, | |
232 image_size, image_size); | |
233 frames_->extractSubset(&this_frame_, subset_rect); | |
234 return this_frame_; | |
235 } | |
236 | |
237 void ThrobberNativeTextButton::Run() { | |
238 DCHECK(running_); | |
239 | |
240 SchedulePaint(); | |
241 } | |
242 | |
128 // ServiceButtonsView ---------------------------------------------------------- | 243 // ServiceButtonsView ---------------------------------------------------------- |
129 | 244 |
130 // A view that contains all service buttons (i.e. the installed services). | 245 // A view that contains all service buttons (i.e. the installed services). |
131 class ServiceButtonsView : public views::View, | 246 class ServiceButtonsView : public views::View, |
132 public views::ButtonListener { | 247 public views::ButtonListener { |
133 public: | 248 public: |
134 class Delegate { | 249 class Delegate { |
135 public: | 250 public: |
136 // Called when a service button is clicked. |index| is the index of the | 251 // Called when a service button is clicked. |index| is the index of the |
137 // service button in the model. | 252 // service button in the model. |
138 virtual void OnServiceButtonClicked( | 253 virtual void OnServiceButtonClicked( |
139 const WebIntentPickerModel::InstalledService& service) = 0; | 254 const WebIntentPickerModel::InstalledService& service) = 0; |
140 | 255 |
141 protected: | 256 protected: |
142 virtual ~Delegate() {} | 257 virtual ~Delegate() {} |
143 }; | 258 }; |
144 | 259 |
145 ServiceButtonsView(const WebIntentPickerModel* model, Delegate* delegate); | 260 ServiceButtonsView(const WebIntentPickerModel* model, Delegate* delegate); |
146 virtual ~ServiceButtonsView(); | 261 virtual ~ServiceButtonsView(); |
147 | 262 |
148 // Updates the service button view with new model data. | 263 // Updates the service button view with new model data. |
149 void Update(); | 264 void Update(); |
150 | 265 |
266 // Start a throbber on the service button that will launch the service at | |
267 // |url|. | |
268 void StartThrobber(const GURL& url); | |
269 | |
151 // views::ButtonListener implementation. | 270 // views::ButtonListener implementation. |
152 virtual void ButtonPressed(views::Button* sender, | 271 virtual void ButtonPressed(views::Button* sender, |
153 const views::Event& event) OVERRIDE; | 272 const views::Event& event) OVERRIDE; |
154 | 273 |
155 virtual gfx::Size GetPreferredSize() OVERRIDE; | 274 virtual gfx::Size GetPreferredSize() OVERRIDE; |
156 | 275 |
157 protected: | 276 protected: |
158 virtual void OnEnabledChanged() OVERRIDE; | 277 virtual void OnEnabledChanged() OVERRIDE; |
159 | 278 |
160 private: | 279 private: |
(...skipping 26 matching lines...) Expand all Loading... | |
187 cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, GridLayout::USE_PREF, | 306 cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, GridLayout::USE_PREF, |
188 0, 0); | 307 0, 0); |
189 cs->AddPaddingColumn(1, 0); | 308 cs->AddPaddingColumn(1, 0); |
190 | 309 |
191 for (size_t i = 0; i < model_->GetInstalledServiceCount(); ++i) { | 310 for (size_t i = 0; i < model_->GetInstalledServiceCount(); ++i) { |
192 const WebIntentPickerModel::InstalledService& service = | 311 const WebIntentPickerModel::InstalledService& service = |
193 model_->GetInstalledServiceAt(i); | 312 model_->GetInstalledServiceAt(i); |
194 | 313 |
195 grid_layout->StartRow(0, 0); | 314 grid_layout->StartRow(0, 0); |
196 | 315 |
197 views::NativeTextButton* button = | 316 ThrobberNativeTextButton* button = |
198 new views::NativeTextButton(this, service.title); | 317 new ThrobberNativeTextButton(this, service.title); |
199 button->set_alignment(views::TextButton::ALIGN_LEFT); | 318 button->set_alignment(views::TextButton::ALIGN_LEFT); |
200 button->SetTooltipText(UTF8ToUTF16(service.url.spec().c_str())); | 319 button->SetTooltipText(UTF8ToUTF16(service.url.spec().c_str())); |
201 button->SetIcon(*service.favicon.ToSkBitmap()); | 320 button->SetIcon(*service.favicon.ToSkBitmap()); |
202 button->set_tag(static_cast<int>(i)); | 321 button->set_tag(static_cast<int>(i)); |
203 grid_layout->AddView(button); | 322 grid_layout->AddView(button); |
204 grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | 323 grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); |
205 } | 324 } |
206 | 325 |
207 // Additional space to separate the buttons from the suggestions. | 326 // Additional space to separate the buttons from the suggestions. |
208 grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | 327 grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); |
209 } | 328 } |
210 | 329 |
330 void ServiceButtonsView::StartThrobber(const GURL& url) { | |
331 for (size_t i = 0; i < model_->GetInstalledServiceCount(); ++i) { | |
332 const WebIntentPickerModel::InstalledService& service = | |
333 model_->GetInstalledServiceAt(i); | |
334 if (service.url != url) | |
335 continue; | |
336 | |
337 ThrobberNativeTextButton* button = | |
338 static_cast<ThrobberNativeTextButton*>(child_at(i)); | |
339 button->StartThrobber(); | |
340 return; | |
341 } | |
342 } | |
343 | |
211 void ServiceButtonsView::ButtonPressed(views::Button* sender, | 344 void ServiceButtonsView::ButtonPressed(views::Button* sender, |
212 const views::Event& event) { | 345 const views::Event& event) { |
213 size_t index = static_cast<size_t>(sender->tag()); | 346 size_t index = static_cast<size_t>(sender->tag()); |
214 delegate_->OnServiceButtonClicked(model_->GetInstalledServiceAt(index)); | 347 delegate_->OnServiceButtonClicked(model_->GetInstalledServiceAt(index)); |
215 } | 348 } |
216 | 349 |
217 gfx::Size ServiceButtonsView::GetPreferredSize() { | 350 gfx::Size ServiceButtonsView::GetPreferredSize() { |
218 // If there are no service buttons, hide this view. | 351 // If there are no service buttons, hide this view. |
219 if (model_->GetInstalledServiceCount() == 0) | 352 if (model_->GetInstalledServiceCount() == 0) |
220 return gfx::Size(); | 353 return gfx::Size(); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
344 // A delegate to respond to button presses and clicked links. | 477 // A delegate to respond to button presses and clicked links. |
345 Delegate* delegate_; | 478 Delegate* delegate_; |
346 | 479 |
347 // The icon of the extension. | 480 // The icon of the extension. |
348 views::ImageView* icon_; | 481 views::ImageView* icon_; |
349 | 482 |
350 // The title of the extension, which links to the CWS detailed description of | 483 // The title of the extension, which links to the CWS detailed description of |
351 // this extension. | 484 // this extension. |
352 views::Link* title_link_; | 485 views::Link* title_link_; |
353 | 486 |
354 // A throbber to display when the extension is being installed. | |
355 views::Throbber* throbber_; | |
356 | |
357 // The star rating of this extension. | 487 // The star rating of this extension. |
358 StarsView* stars_; | 488 StarsView* stars_; |
359 | 489 |
360 // A button to install the extension. | 490 // A button to install the extension. |
361 views::NativeTextButton* install_button_; | 491 ThrobberNativeTextButton* install_button_; |
362 | 492 |
363 DISALLOW_COPY_AND_ASSIGN(SuggestedExtensionsRowView); | 493 DISALLOW_COPY_AND_ASSIGN(SuggestedExtensionsRowView); |
364 }; | 494 }; |
365 | 495 |
366 SuggestedExtensionsRowView::SuggestedExtensionsRowView( | 496 SuggestedExtensionsRowView::SuggestedExtensionsRowView( |
367 const WebIntentPickerModel::SuggestedExtension* extension, | 497 const WebIntentPickerModel::SuggestedExtension* extension, |
368 Delegate* delegate) | 498 Delegate* delegate) |
369 : extension_(extension), | 499 : extension_(extension), |
370 delegate_(delegate) { | 500 delegate_(delegate) { |
371 SetLayoutManager(new SuggestedExtensionsLayout); | 501 SetLayoutManager(new SuggestedExtensionsLayout); |
372 | 502 |
373 icon_ = new views::ImageView(); | 503 icon_ = new views::ImageView(); |
374 icon_->SetImage(extension_->icon.ToSkBitmap()); | 504 icon_->SetImage(extension_->icon.ToSkBitmap()); |
375 AddChildView(icon_); | 505 AddChildView(icon_); |
376 | 506 |
377 string16 elided_title = ui::ElideText( | 507 string16 elided_title = ui::ElideText( |
378 extension_->title, gfx::Font(), kTitleLinkMaxWidth, ui::ELIDE_AT_END); | 508 extension_->title, gfx::Font(), kTitleLinkMaxWidth, ui::ELIDE_AT_END); |
379 title_link_ = new views::Link(elided_title); | 509 title_link_ = new views::Link(elided_title); |
380 title_link_->set_listener(this); | 510 title_link_->set_listener(this); |
381 AddChildView(title_link_); | 511 AddChildView(title_link_); |
382 | 512 |
383 throbber_ = new views::Throbber(60, true); | |
384 throbber_->SetVisible(false); | |
385 AddChildView(throbber_); | |
386 | |
387 stars_ = new StarsView(extension_->average_rating); | 513 stars_ = new StarsView(extension_->average_rating); |
388 AddChildView(stars_); | 514 AddChildView(stars_); |
389 | 515 |
390 install_button_= new views::NativeTextButton( | 516 install_button_= new ThrobberNativeTextButton( |
391 this, l10n_util::GetStringUTF16(IDS_INTENT_PICKER_INSTALL_EXTENSION)); | 517 this, l10n_util::GetStringUTF16(IDS_INTENT_PICKER_INSTALL_EXTENSION)); |
392 AddChildView(install_button_); | 518 AddChildView(install_button_); |
393 } | 519 } |
394 | 520 |
395 SuggestedExtensionsRowView::~SuggestedExtensionsRowView() { | 521 SuggestedExtensionsRowView::~SuggestedExtensionsRowView() { |
396 } | 522 } |
397 | 523 |
398 void SuggestedExtensionsRowView::ButtonPressed(views::Button* sender, | 524 void SuggestedExtensionsRowView::ButtonPressed(views::Button* sender, |
399 const views::Event& event) { | 525 const views::Event& event) { |
400 delegate_->OnExtensionInstallClicked(extension_->id); | 526 delegate_->OnExtensionInstallClicked(extension_->id); |
401 } | 527 } |
402 | 528 |
403 void SuggestedExtensionsRowView::LinkClicked(views::Link* source, | 529 void SuggestedExtensionsRowView::LinkClicked(views::Link* source, |
404 int event_flags) { | 530 int event_flags) { |
405 delegate_->OnExtensionLinkClicked(extension_->id); | 531 delegate_->OnExtensionLinkClicked(extension_->id); |
406 } | 532 } |
407 | 533 |
408 void SuggestedExtensionsRowView::StartThrobber() { | 534 void SuggestedExtensionsRowView::StartThrobber() { |
409 stars_->SetVisible(false); | 535 install_button_->StartThrobber(); |
410 install_button_->SetVisible(false); | 536 install_button_->SetText(string16()); |
411 throbber_->SetVisible(true); | |
412 throbber_->Start(); | |
413 Layout(); | |
414 } | 537 } |
415 | 538 |
416 void SuggestedExtensionsRowView::StopThrobber() { | 539 void SuggestedExtensionsRowView::StopThrobber() { |
417 stars_->SetVisible(true); | 540 install_button_->StopThrobber(); |
418 install_button_->SetVisible(true); | 541 install_button_->SetText( |
419 throbber_->SetVisible(false); | 542 l10n_util::GetStringUTF16(IDS_INTENT_PICKER_INSTALL_EXTENSION)); |
420 throbber_->Stop(); | |
421 Layout(); | |
422 } | 543 } |
423 | 544 |
424 void SuggestedExtensionsRowView::OnEnabledChanged() { | 545 void SuggestedExtensionsRowView::OnEnabledChanged() { |
425 title_link_->SetEnabled(enabled()); | 546 title_link_->SetEnabled(enabled()); |
426 stars_->SetVisible(enabled()); | 547 stars_->SetEnabled(enabled()); |
427 install_button_->SetVisible(enabled()); | 548 install_button_->SetEnabled(enabled()); |
428 View::OnEnabledChanged(); | 549 View::OnEnabledChanged(); |
429 Layout(); | 550 Layout(); |
430 } | 551 } |
431 | 552 |
432 void SuggestedExtensionsRowView::PaintChildren(gfx::Canvas* canvas) { | 553 void SuggestedExtensionsRowView::PaintChildren(gfx::Canvas* canvas) { |
433 View::PaintChildren(canvas); | 554 View::PaintChildren(canvas); |
434 if (!enabled()) | 555 if (!enabled()) |
435 canvas->FillRect(GetLocalBounds(), kHalfOpacityWhite); | 556 canvas->FillRect(GetLocalBounds(), kHalfOpacityWhite); |
436 } | 557 } |
437 | 558 |
438 // SuggestedExtensionsView ----------------------------------------------------- | 559 // SuggestedExtensionsView ----------------------------------------------------- |
439 | 560 |
440 // A view that contains suggested extensions from the Chrome Web Store that | 561 // A view that contains suggested extensions from the Chrome Web Store that |
441 // provide an intent service matching the action/type pair. | 562 // provide an intent service matching the action/type pair. |
442 // This view also displays the "More suggestions" link which searches the | |
443 // Chrome Web Store for more extensions. | |
444 class SuggestedExtensionsView : public views::View { | 563 class SuggestedExtensionsView : public views::View { |
445 public: | 564 public: |
446 SuggestedExtensionsView(const WebIntentPickerModel* model, | 565 SuggestedExtensionsView(const WebIntentPickerModel* model, |
447 SuggestedExtensionsRowView::Delegate* delegate); | 566 SuggestedExtensionsRowView::Delegate* delegate); |
448 | 567 |
449 virtual ~SuggestedExtensionsView(); | 568 virtual ~SuggestedExtensionsView(); |
450 | 569 |
451 void Clear(); | 570 void Clear(); |
452 | 571 |
453 // Update the view to the new model data. | 572 // Update the view to the new model data. |
454 void Update(); | 573 void Update(); |
455 | 574 |
456 // Show the install throbber for the row containing |extension_id|. This | 575 // Show the install throbber for the row containing |extension_id|. This |
457 // function also hides hides and disables other buttons and links. | 576 // function also hides hides and disables other buttons and links. |
458 void StartThrobber(const string16& extension_id); | 577 void StartThrobber(const string16& extension_id); |
459 | 578 |
460 // Hide the install throbber. This function re-enables all buttons and links. | 579 // Hide the install throbber. This function re-enables all buttons and links. |
461 void StopThrobber(); | 580 void StopThrobber(); |
462 | 581 |
582 protected: | |
583 virtual void OnEnabledChanged() OVERRIDE; | |
584 | |
463 private: | 585 private: |
464 const WebIntentPickerModel* model_; | 586 const WebIntentPickerModel* model_; |
465 SuggestedExtensionsRowView::Delegate* delegate_; | 587 SuggestedExtensionsRowView::Delegate* delegate_; |
466 | 588 |
467 DISALLOW_COPY_AND_ASSIGN(SuggestedExtensionsView); | 589 DISALLOW_COPY_AND_ASSIGN(SuggestedExtensionsView); |
468 }; | 590 }; |
469 | 591 |
470 SuggestedExtensionsView::SuggestedExtensionsView( | 592 SuggestedExtensionsView::SuggestedExtensionsView( |
471 const WebIntentPickerModel* model, | 593 const WebIntentPickerModel* model, |
472 SuggestedExtensionsRowView::Delegate* delegate) | 594 SuggestedExtensionsRowView::Delegate* delegate) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
511 | 633 |
512 void SuggestedExtensionsView::StopThrobber() { | 634 void SuggestedExtensionsView::StopThrobber() { |
513 for (size_t i = 0; i < model_->GetSuggestedExtensionCount(); ++i) { | 635 for (size_t i = 0; i < model_->GetSuggestedExtensionCount(); ++i) { |
514 SuggestedExtensionsRowView* row = | 636 SuggestedExtensionsRowView* row = |
515 static_cast<SuggestedExtensionsRowView*>(child_at(i)); | 637 static_cast<SuggestedExtensionsRowView*>(child_at(i)); |
516 row->SetEnabled(true); | 638 row->SetEnabled(true); |
517 row->StopThrobber(); | 639 row->StopThrobber(); |
518 } | 640 } |
519 } | 641 } |
520 | 642 |
643 void SuggestedExtensionsView::OnEnabledChanged() { | |
644 EnableChildViews(this, enabled()); | |
645 View::OnEnabledChanged(); | |
646 } | |
647 | |
521 } // namespace | 648 } // namespace |
522 | 649 |
523 // WebIntentPickerViews -------------------------------------------------------- | 650 // WebIntentPickerViews -------------------------------------------------------- |
524 | 651 |
525 // Views implementation of WebIntentPicker. | 652 // Views implementation of WebIntentPicker. |
526 class WebIntentPickerViews : public views::ButtonListener, | 653 class WebIntentPickerViews : public views::ButtonListener, |
527 public views::DialogDelegate, | 654 public views::DialogDelegate, |
528 public views::LinkListener, | 655 public views::LinkListener, |
529 public WebIntentPicker, | 656 public WebIntentPicker, |
530 public WebIntentPickerModelObserver, | 657 public WebIntentPickerModelObserver, |
(...skipping 19 matching lines...) Expand all Loading... | |
550 virtual int GetDialogButtons() const OVERRIDE; | 677 virtual int GetDialogButtons() const OVERRIDE; |
551 | 678 |
552 // LinkListener implementation. | 679 // LinkListener implementation. |
553 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; | 680 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; |
554 | 681 |
555 // WebIntentPicker implementation. | 682 // WebIntentPicker implementation. |
556 virtual void Close() OVERRIDE; | 683 virtual void Close() OVERRIDE; |
557 virtual void SetActionString(const string16& action) OVERRIDE; | 684 virtual void SetActionString(const string16& action) OVERRIDE; |
558 virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE; | 685 virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE; |
559 virtual void OnExtensionInstallFailure(const std::string& id) OVERRIDE; | 686 virtual void OnExtensionInstallFailure(const std::string& id) OVERRIDE; |
687 virtual void OnInlineDispositionWebContentsLoaded( | |
688 content::WebContents* web_contents) OVERRIDE; | |
560 | 689 |
561 // WebIntentPickerModelObserver implementation. | 690 // WebIntentPickerModelObserver implementation. |
562 virtual void OnModelChanged(WebIntentPickerModel* model) OVERRIDE; | 691 virtual void OnModelChanged(WebIntentPickerModel* model) OVERRIDE; |
563 virtual void OnFaviconChanged(WebIntentPickerModel* model, | 692 virtual void OnFaviconChanged(WebIntentPickerModel* model, |
564 size_t index) OVERRIDE; | 693 size_t index) OVERRIDE; |
565 virtual void OnExtensionIconChanged(WebIntentPickerModel* model, | 694 virtual void OnExtensionIconChanged(WebIntentPickerModel* model, |
566 const string16& extension_id) OVERRIDE; | 695 const string16& extension_id) OVERRIDE; |
567 virtual void OnInlineDisposition(WebIntentPickerModel* model, | 696 virtual void OnInlineDisposition(WebIntentPickerModel* model, |
568 const GURL& url) OVERRIDE; | 697 const GURL& url) OVERRIDE; |
569 | 698 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
618 | 747 |
619 // A weak pointer to the constrained window. | 748 // A weak pointer to the constrained window. |
620 ConstrainedWindowViews* window_; | 749 ConstrainedWindowViews* window_; |
621 | 750 |
622 // A weak pointer to the more suggestions link. | 751 // A weak pointer to the more suggestions link. |
623 views::Link* more_suggestions_link_; | 752 views::Link* more_suggestions_link_; |
624 | 753 |
625 // A weak pointer to the choose another service link. | 754 // A weak pointer to the choose another service link. |
626 views::Link* choose_another_service_link_; | 755 views::Link* choose_another_service_link_; |
627 | 756 |
757 // Set to true when displaying the inline disposition web contents. Used to | |
758 // prevent laying out the inline disposition widgets twice. | |
759 bool displaying_web_contents_; | |
760 | |
628 DISALLOW_COPY_AND_ASSIGN(WebIntentPickerViews); | 761 DISALLOW_COPY_AND_ASSIGN(WebIntentPickerViews); |
629 }; | 762 }; |
630 | 763 |
631 // static | 764 // static |
632 WebIntentPicker* WebIntentPicker::Create(Browser* browser, | 765 WebIntentPicker* WebIntentPicker::Create(Browser* browser, |
633 TabContentsWrapper* wrapper, | 766 TabContentsWrapper* wrapper, |
634 WebIntentPickerDelegate* delegate, | 767 WebIntentPickerDelegate* delegate, |
635 WebIntentPickerModel* model) { | 768 WebIntentPickerModel* model) { |
636 WebIntentPickerViews* picker = | 769 WebIntentPickerViews* picker = |
637 new WebIntentPickerViews(browser, wrapper, delegate, model); | 770 new WebIntentPickerViews(browser, wrapper, delegate, model); |
638 | 771 |
639 return picker; | 772 return picker; |
640 } | 773 } |
641 | 774 |
642 WebIntentPickerViews::WebIntentPickerViews(Browser* browser, | 775 WebIntentPickerViews::WebIntentPickerViews(Browser* browser, |
643 TabContentsWrapper* wrapper, | 776 TabContentsWrapper* wrapper, |
644 WebIntentPickerDelegate* delegate, | 777 WebIntentPickerDelegate* delegate, |
645 WebIntentPickerModel* model) | 778 WebIntentPickerModel* model) |
646 : delegate_(delegate), | 779 : delegate_(delegate), |
647 model_(model), | 780 model_(model), |
648 service_buttons_(NULL), | 781 service_buttons_(NULL), |
649 action_label_(NULL), | 782 action_label_(NULL), |
650 suggestions_label_(NULL), | 783 suggestions_label_(NULL), |
651 extensions_(NULL), | 784 extensions_(NULL), |
652 browser_(browser), | 785 browser_(browser), |
653 contents_(NULL), | 786 contents_(NULL), |
654 window_(NULL), | 787 window_(NULL), |
655 more_suggestions_link_(NULL), | 788 more_suggestions_link_(NULL), |
656 choose_another_service_link_(NULL) { | 789 choose_another_service_link_(NULL), |
790 displaying_web_contents_(false) { | |
657 model_->set_observer(this); | 791 model_->set_observer(this); |
658 InitContents(); | 792 InitContents(); |
659 | 793 |
660 // Show the dialog. | 794 // Show the dialog. |
661 window_ = new ConstrainedWindowViews(wrapper, this); | 795 window_ = new ConstrainedWindowViews(wrapper, this); |
662 } | 796 } |
663 | 797 |
664 WebIntentPickerViews::~WebIntentPickerViews() { | 798 WebIntentPickerViews::~WebIntentPickerViews() { |
665 model_->set_observer(NULL); | 799 model_->set_observer(NULL); |
666 } | 800 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
726 | 860 |
727 void WebIntentPickerViews::OnExtensionInstallFailure(const std::string& id) { | 861 void WebIntentPickerViews::OnExtensionInstallFailure(const std::string& id) { |
728 service_buttons_->SetEnabled(true); | 862 service_buttons_->SetEnabled(true); |
729 extensions_->StopThrobber(); | 863 extensions_->StopThrobber(); |
730 more_suggestions_link_->SetEnabled(true); | 864 more_suggestions_link_->SetEnabled(true); |
731 contents_->Layout(); | 865 contents_->Layout(); |
732 | 866 |
733 // TODO(binji): What to display to user on failure? | 867 // TODO(binji): What to display to user on failure? |
734 } | 868 } |
735 | 869 |
736 void WebIntentPickerViews::OnModelChanged(WebIntentPickerModel* model) { | 870 void WebIntentPickerViews::OnInlineDispositionWebContentsLoaded( |
737 if (model->GetInstalledServiceCount() == 0) { | 871 content::WebContents* web_contents) { |
738 suggestions_label_->SetText(l10n_util::GetStringUTF16( | 872 if (displaying_web_contents_) |
739 IDS_INTENT_PICKER_GET_MORE_SERVICES_NONE_INSTALLED)); | 873 return; |
740 } else { | |
741 suggestions_label_->SetText( | |
742 l10n_util::GetStringUTF16(IDS_INTENT_PICKER_GET_MORE_SERVICES)); | |
743 } | |
744 | |
745 service_buttons_->Update(); | |
746 extensions_->Update(); | |
747 contents_->Layout(); | |
748 SizeToContents(); | |
749 } | |
750 | |
751 void WebIntentPickerViews::OnFaviconChanged( | |
752 WebIntentPickerModel* model, size_t index) { | |
753 service_buttons_->Update(); | |
754 contents_->Layout(); | |
755 SizeToContents(); | |
756 } | |
757 | |
758 void WebIntentPickerViews::OnExtensionIconChanged( | |
759 WebIntentPickerModel* model, | |
760 const string16& extension_id) { | |
761 extensions_->Update(); | |
762 contents_->Layout(); | |
763 SizeToContents(); | |
764 } | |
765 | |
766 void WebIntentPickerViews::OnInlineDisposition( | |
767 WebIntentPickerModel* model, const GURL& url) { | |
768 WebContents* web_contents = WebContents::Create( | |
769 browser_->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL); | |
770 inline_disposition_delegate_.reset(new WebIntentInlineDispositionDelegate); | |
771 web_contents->SetDelegate(inline_disposition_delegate_.get()); | |
772 | |
773 const WebIntentPickerModel::InstalledService* service = | |
774 model->GetInstalledServiceWithURL(url); | |
775 DCHECK(service); | |
776 | |
777 // Must call this immediately after WebContents creation to avoid race | |
778 // with load. | |
779 delegate_->OnInlineDispositionWebContentsCreated(web_contents); | |
780 | |
781 TabContentsContainer* tab_contents_container = new TabContentsContainer; | |
782 | |
783 web_contents->GetController().LoadURL( | |
784 url, | |
785 content::Referrer(), | |
786 content::PAGE_TRANSITION_START_PAGE, | |
787 std::string()); | |
788 | 874 |
789 // Replace the picker with the inline disposition. | 875 // Replace the picker with the inline disposition. |
790 contents_->RemoveAllChildViews(true); | 876 contents_->RemoveAllChildViews(true); |
791 | 877 |
792 views::GridLayout* grid_layout = new views::GridLayout(contents_); | 878 views::GridLayout* grid_layout = new views::GridLayout(contents_); |
793 contents_->SetLayoutManager(grid_layout); | 879 contents_->SetLayoutManager(grid_layout); |
794 | 880 |
795 grid_layout->SetInsets(kContentAreaBorder, kContentAreaBorder, | 881 grid_layout->SetInsets(kContentAreaBorder, kContentAreaBorder, |
796 kContentAreaBorder, kContentAreaBorder); | 882 kContentAreaBorder, kContentAreaBorder); |
797 views::ColumnSet* header_cs = grid_layout->AddColumnSet(0); | 883 views::ColumnSet* header_cs = grid_layout->AddColumnSet(0); |
798 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, | 884 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, |
799 GridLayout::USE_PREF, 0, 0); // Icon. | 885 GridLayout::USE_PREF, 0, 0); // Icon. |
800 header_cs->AddPaddingColumn(0, 4); | 886 header_cs->AddPaddingColumn(0, 4); |
801 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, | 887 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, |
802 GridLayout::USE_PREF, 0, 0); // Title. | 888 GridLayout::USE_PREF, 0, 0); // Title. |
803 header_cs->AddPaddingColumn(0, 4); | 889 header_cs->AddPaddingColumn(0, 4); |
804 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, | 890 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, |
805 GridLayout::USE_PREF, 0, 0); // Link. | 891 GridLayout::USE_PREF, 0, 0); // Link. |
806 header_cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing); | 892 header_cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing); |
807 #if defined(USE_CLOSE_BUTTON) | 893 #if defined(USE_CLOSE_BUTTON) |
808 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, | 894 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, |
809 GridLayout::USE_PREF, 0, 0); // Close Button. | 895 GridLayout::USE_PREF, 0, 0); // Close Button. |
810 #endif | 896 #endif |
811 | 897 |
812 views::ColumnSet* full_cs = grid_layout->AddColumnSet(1); | 898 views::ColumnSet* full_cs = grid_layout->AddColumnSet(1); |
813 full_cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, | 899 full_cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, |
814 GridLayout::USE_PREF, 0, 0); | 900 GridLayout::USE_PREF, 0, 0); |
815 | 901 |
902 const WebIntentPickerModel::InstalledService* service = | |
903 model_->GetInstalledServiceWithURL(model_->inline_disposition_url()); | |
904 | |
816 // Header row. | 905 // Header row. |
817 grid_layout->StartRow(0, 0); | 906 grid_layout->StartRow(0, 0); |
818 views::ImageView* icon = new views::ImageView(); | 907 views::ImageView* icon = new views::ImageView(); |
819 icon->SetImage(service->favicon.ToSkBitmap()); | 908 icon->SetImage(service->favicon.ToSkBitmap()); |
820 grid_layout->AddView(icon); | 909 grid_layout->AddView(icon); |
821 | 910 |
822 string16 elided_title = ui::ElideText( | 911 string16 elided_title = ui::ElideText( |
823 service->title, gfx::Font(), kTitleLinkMaxWidth, ui::ELIDE_AT_END); | 912 service->title, gfx::Font(), kTitleLinkMaxWidth, ui::ELIDE_AT_END); |
824 views::Label* title = new views::Label(elided_title); | 913 views::Label* title = new views::Label(elided_title); |
825 grid_layout->AddView(title); | 914 grid_layout->AddView(title); |
826 | 915 |
827 choose_another_service_link_ = new views::Link( | 916 choose_another_service_link_ = new views::Link( |
828 l10n_util::GetStringUTF16(IDS_INTENT_PICKER_USE_ALTERNATE_SERVICE)); | 917 l10n_util::GetStringUTF16(IDS_INTENT_PICKER_USE_ALTERNATE_SERVICE)); |
829 grid_layout->AddView(choose_another_service_link_); | 918 grid_layout->AddView(choose_another_service_link_); |
830 | 919 |
831 #if defined(USE_CLOSE_BUTTON) | 920 #if defined(USE_CLOSE_BUTTON) |
832 grid_layout->AddView(CreateCloseButton()); | 921 grid_layout->AddView(CreateCloseButton()); |
833 #endif | 922 #endif |
834 | 923 |
835 // Inline web contents row. | 924 // Inline web contents row. |
836 grid_layout->StartRow(0, 1); | 925 grid_layout->StartRow(0, 1); |
926 TabContentsContainer* tab_contents_container = new TabContentsContainer; | |
837 grid_layout->AddView(tab_contents_container, 1, 1, GridLayout::CENTER, | 927 grid_layout->AddView(tab_contents_container, 1, 1, GridLayout::CENTER, |
838 GridLayout::CENTER, kDialogMinWidth, 140); | 928 GridLayout::CENTER, kDialogMinWidth, 140); |
839 | 929 |
840 // The contents can only be changed after the child is added to view | 930 // The contents can only be changed after the child is added to view |
841 // hierarchy. | 931 // hierarchy. |
842 tab_contents_container->ChangeWebContents(web_contents); | 932 tab_contents_container->ChangeWebContents(web_contents); |
843 | |
844 contents_->Layout(); | 933 contents_->Layout(); |
845 SizeToContents(); | 934 SizeToContents(); |
935 displaying_web_contents_ = true; | |
936 } | |
937 | |
938 void WebIntentPickerViews::OnModelChanged(WebIntentPickerModel* model) { | |
939 if (model->GetInstalledServiceCount() == 0) { | |
940 suggestions_label_->SetText(l10n_util::GetStringUTF16( | |
941 IDS_INTENT_PICKER_GET_MORE_SERVICES_NONE_INSTALLED)); | |
942 } else { | |
943 suggestions_label_->SetText( | |
944 l10n_util::GetStringUTF16(IDS_INTENT_PICKER_GET_MORE_SERVICES)); | |
945 } | |
946 | |
947 service_buttons_->Update(); | |
948 extensions_->Update(); | |
949 contents_->Layout(); | |
950 SizeToContents(); | |
951 } | |
952 | |
953 void WebIntentPickerViews::OnFaviconChanged( | |
954 WebIntentPickerModel* model, size_t index) { | |
955 service_buttons_->Update(); | |
956 contents_->Layout(); | |
957 SizeToContents(); | |
958 } | |
959 | |
960 void WebIntentPickerViews::OnExtensionIconChanged( | |
961 WebIntentPickerModel* model, | |
962 const string16& extension_id) { | |
963 extensions_->Update(); | |
964 contents_->Layout(); | |
965 SizeToContents(); | |
966 } | |
967 | |
968 void WebIntentPickerViews::OnInlineDisposition( | |
969 WebIntentPickerModel* model, const GURL& url) { | |
970 WebContents* web_contents = WebContents::Create( | |
971 browser_->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL); | |
972 inline_disposition_delegate_.reset( | |
973 new WebIntentInlineDispositionDelegate(this)); | |
974 web_contents->SetDelegate(inline_disposition_delegate_.get()); | |
975 | |
976 const WebIntentPickerModel::InstalledService* service = | |
977 model->GetInstalledServiceWithURL(url); | |
978 DCHECK(service); | |
979 | |
980 // Must call this immediately after WebContents creation to avoid race | |
981 // with load. | |
982 delegate_->OnInlineDispositionWebContentsCreated(web_contents); | |
983 web_contents->GetController().LoadURL( | |
984 url, | |
985 content::Referrer(), | |
986 content::PAGE_TRANSITION_START_PAGE, | |
987 std::string()); | |
988 | |
989 // Disable all buttons and show throbber. | |
990 service_buttons_->SetEnabled(false); | |
991 service_buttons_->StartThrobber(url); | |
992 extensions_->SetEnabled(false); | |
993 more_suggestions_link_->SetEnabled(false); | |
994 contents_->Layout(); | |
846 } | 995 } |
847 | 996 |
848 void WebIntentPickerViews::OnServiceButtonClicked( | 997 void WebIntentPickerViews::OnServiceButtonClicked( |
849 const WebIntentPickerModel::InstalledService& service) { | 998 const WebIntentPickerModel::InstalledService& service) { |
850 delegate_->OnServiceChosen(service.url, service.disposition); | 999 delegate_->OnServiceChosen(service.url, service.disposition); |
851 } | 1000 } |
852 | 1001 |
853 void WebIntentPickerViews::OnExtensionInstallClicked( | 1002 void WebIntentPickerViews::OnExtensionInstallClicked( |
854 const string16& extension_id) { | 1003 const string16& extension_id) { |
855 service_buttons_->SetEnabled(false); | 1004 service_buttons_->SetEnabled(false); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
966 views::ImageButton* close_button = new views::ImageButton(this); | 1115 views::ImageButton* close_button = new views::ImageButton(this); |
967 close_button->SetImage(views::CustomButton::BS_NORMAL, | 1116 close_button->SetImage(views::CustomButton::BS_NORMAL, |
968 rb.GetBitmapNamed(IDR_CLOSE_BAR)); | 1117 rb.GetBitmapNamed(IDR_CLOSE_BAR)); |
969 close_button->SetImage(views::CustomButton::BS_HOT, | 1118 close_button->SetImage(views::CustomButton::BS_HOT, |
970 rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); | 1119 rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); |
971 close_button->SetImage(views::CustomButton::BS_PUSHED, | 1120 close_button->SetImage(views::CustomButton::BS_PUSHED, |
972 rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); | 1121 rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); |
973 return close_button; | 1122 return close_button; |
974 } | 1123 } |
975 #endif | 1124 #endif |
OLD | NEW |