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