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 <vector> | 5 #include <vector> |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/i18n/rtl.h" | 9 #include "base/i18n/rtl.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
12 #include "chrome/browser/extensions/bundle_installer.h" | 12 #include "chrome/browser/extensions/bundle_installer.h" |
13 #include "chrome/browser/extensions/extension_install_dialog.h" | 13 #include "chrome/browser/extensions/extension_install_dialog.h" |
14 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
15 #include "chrome/common/extensions/extension.h" | 15 #include "chrome/common/extensions/extension.h" |
16 #include "content/public/browser/page_navigator.h" | 16 #include "content/public/browser/page_navigator.h" |
17 #include "grit/generated_resources.h" | 17 #include "grit/generated_resources.h" |
| 18 #include "grit/theme_resources.h" |
| 19 #include "ui/base/animation/animation_delegate.h" |
| 20 #include "ui/base/animation/slide_animation.h" |
18 #include "ui/base/l10n/l10n_util.h" | 21 #include "ui/base/l10n/l10n_util.h" |
19 #include "ui/base/resource/resource_bundle.h" | 22 #include "ui/base/resource/resource_bundle.h" |
| 23 #include "ui/gfx/point3.h" |
| 24 #include "ui/gfx/transform.h" |
20 #include "ui/views/border.h" | 25 #include "ui/views/border.h" |
21 #include "ui/views/controls/image_view.h" | 26 #include "ui/views/controls/image_view.h" |
22 #include "ui/views/controls/label.h" | 27 #include "ui/views/controls/label.h" |
23 #include "ui/views/controls/link.h" | 28 #include "ui/views/controls/link.h" |
24 #include "ui/views/controls/link_listener.h" | 29 #include "ui/views/controls/link_listener.h" |
25 #include "ui/views/controls/separator.h" | 30 #include "ui/views/controls/separator.h" |
26 #include "ui/views/layout/box_layout.h" | 31 #include "ui/views/layout/box_layout.h" |
27 #include "ui/views/layout/grid_layout.h" | 32 #include "ui/views/layout/grid_layout.h" |
28 #include "ui/views/layout/layout_constants.h" | 33 #include "ui/views/layout/layout_constants.h" |
29 #include "ui/views/view.h" | 34 #include "ui/views/view.h" |
(...skipping 30 matching lines...) Expand all Loading... |
60 | 65 |
61 const int kRatingFontSizeDelta = -1; | 66 const int kRatingFontSizeDelta = -1; |
62 | 67 |
63 void AddResourceIcon(const gfx::ImageSkia* skia_image, void* data) { | 68 void AddResourceIcon(const gfx::ImageSkia* skia_image, void* data) { |
64 views::View* parent = static_cast<views::View*>(data); | 69 views::View* parent = static_cast<views::View*>(data); |
65 views::ImageView* image_view = new views::ImageView(); | 70 views::ImageView* image_view = new views::ImageView(); |
66 image_view->SetImage(*skia_image); | 71 image_view->SetImage(*skia_image); |
67 parent->AddChildView(image_view); | 72 parent->AddChildView(image_view); |
68 } | 73 } |
69 | 74 |
70 } // namespace | 75 // Creates a string for displaying |message| to the user. If it has to look |
| 76 // like a entry in a bullet point list, one is added. |
| 77 string16 PrepareForDisplay(const string16& message, bool bullet_point) { |
| 78 return bullet_point ? l10n_util::GetStringFUTF16( |
| 79 IDS_EXTENSION_PERMISSION_LINE, |
| 80 message) : message; |
| 81 } |
71 | 82 |
72 // Implements the extension installation dialog for TOOLKIT_VIEWS. | 83 // Implements the extension installation dialog for TOOLKIT_VIEWS. |
73 class ExtensionInstallDialogView : public views::DialogDelegateView, | 84 class ExtensionInstallDialogView : public views::DialogDelegateView, |
74 public views::LinkListener { | 85 public views::LinkListener { |
75 public: | 86 public: |
76 ExtensionInstallDialogView(content::PageNavigator* navigator, | 87 ExtensionInstallDialogView(content::PageNavigator* navigator, |
77 ExtensionInstallPrompt::Delegate* delegate, | 88 ExtensionInstallPrompt::Delegate* delegate, |
78 const ExtensionInstallPrompt::Prompt& prompt); | 89 const ExtensionInstallPrompt::Prompt& prompt); |
79 virtual ~ExtensionInstallDialogView(); | 90 virtual ~ExtensionInstallDialogView(); |
80 | 91 |
| 92 // Changes the size of the containing widget to match the preferred size |
| 93 // of this dialog. |
| 94 void SizeToContents(); |
| 95 |
81 private: | 96 private: |
82 // views::DialogDelegateView: | 97 // views::DialogDelegateView: |
83 virtual string16 GetDialogButtonLabel(ui::DialogButton button) const OVERRIDE; | 98 virtual string16 GetDialogButtonLabel(ui::DialogButton button) const OVERRIDE; |
84 virtual int GetDefaultDialogButton() const OVERRIDE; | 99 virtual int GetDefaultDialogButton() const OVERRIDE; |
85 virtual bool Cancel() OVERRIDE; | 100 virtual bool Cancel() OVERRIDE; |
86 virtual bool Accept() OVERRIDE; | 101 virtual bool Accept() OVERRIDE; |
87 | 102 |
88 // views::WidgetDelegate: | 103 // views::WidgetDelegate: |
89 virtual ui::ModalType GetModalType() const OVERRIDE; | 104 virtual ui::ModalType GetModalType() const OVERRIDE; |
90 virtual string16 GetWindowTitle() const OVERRIDE; | 105 virtual string16 GetWindowTitle() const OVERRIDE; |
(...skipping 10 matching lines...) Expand all Loading... |
101 return prompt_.type() == ExtensionInstallPrompt::BUNDLE_INSTALL_PROMPT; | 116 return prompt_.type() == ExtensionInstallPrompt::BUNDLE_INSTALL_PROMPT; |
102 } | 117 } |
103 | 118 |
104 content::PageNavigator* navigator_; | 119 content::PageNavigator* navigator_; |
105 ExtensionInstallPrompt::Delegate* delegate_; | 120 ExtensionInstallPrompt::Delegate* delegate_; |
106 ExtensionInstallPrompt::Prompt prompt_; | 121 ExtensionInstallPrompt::Prompt prompt_; |
107 | 122 |
108 DISALLOW_COPY_AND_ASSIGN(ExtensionInstallDialogView); | 123 DISALLOW_COPY_AND_ASSIGN(ExtensionInstallDialogView); |
109 }; | 124 }; |
110 | 125 |
| 126 // A view to display a single IssueAdviceInfoEntry. |
| 127 class IssueAdviceView : public views::View, |
| 128 public ui::AnimationDelegate { |
| 129 public: |
| 130 IssueAdviceView(ExtensionInstallDialogView* owner, |
| 131 const IssueAdviceInfoEntry& issue_advice, |
| 132 int horizontal_space); |
| 133 virtual ~IssueAdviceView() {} |
| 134 |
| 135 // Implementation of views::View: |
| 136 virtual bool OnMousePressed(const views::MouseEvent& event) OVERRIDE; |
| 137 virtual void OnMouseReleased(const views::MouseEvent& event) OVERRIDE; |
| 138 virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE; |
| 139 |
| 140 // Implementation of ui::AnimationDelegate: |
| 141 virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE; |
| 142 |
| 143 private: |
| 144 // A view which displays all the details of an IssueAdviceInfoEntry. |
| 145 class DetailsView : public views::View { |
| 146 public: |
| 147 explicit DetailsView(int horizontal_space); |
| 148 virtual ~DetailsView() {} |
| 149 |
| 150 // Implementation of views::View: |
| 151 virtual gfx::Size GetPreferredSize() OVERRIDE; |
| 152 |
| 153 void AddDetail(const string16& detail); |
| 154 |
| 155 // Animates this to be a height proportional to |state|. |
| 156 void AnimateToState(double state); |
| 157 |
| 158 private: |
| 159 views::GridLayout* layout_; |
| 160 double state_; |
| 161 |
| 162 DISALLOW_COPY_AND_ASSIGN(DetailsView); |
| 163 }; |
| 164 |
| 165 // The dialog that owns |this|. It's also an ancestor in the View hierarchy. |
| 166 ExtensionInstallDialogView* owner_; |
| 167 |
| 168 // A view for showing |issue_advice.details|. |
| 169 DetailsView* details_view_; |
| 170 |
| 171 // The '>' zippy control. |
| 172 views::ImageView* arrow_view_; |
| 173 |
| 174 ui::SlideAnimation slide_animation_; |
| 175 |
| 176 DISALLOW_COPY_AND_ASSIGN(IssueAdviceView); |
| 177 }; |
| 178 |
| 179 } // namespace |
| 180 |
111 ExtensionInstallDialogView::ExtensionInstallDialogView( | 181 ExtensionInstallDialogView::ExtensionInstallDialogView( |
112 content::PageNavigator* navigator, | 182 content::PageNavigator* navigator, |
113 ExtensionInstallPrompt::Delegate* delegate, | 183 ExtensionInstallPrompt::Delegate* delegate, |
114 const ExtensionInstallPrompt::Prompt& prompt) | 184 const ExtensionInstallPrompt::Prompt& prompt) |
115 : navigator_(navigator), | 185 : navigator_(navigator), |
116 delegate_(delegate), | 186 delegate_(delegate), |
117 prompt_(prompt) { | 187 prompt_(prompt) { |
118 // Possible grid layouts: | 188 // Possible grid layouts: |
119 // Inline install | 189 // Inline install |
120 // w/ permissions no permissions | 190 // w/ permissions no permissions |
121 // +--------------------+------+ +--------------+------+ | 191 // +--------------------+------+ +--------------+------+ |
122 // | heading | icon | | heading | icon | | 192 // | heading | icon | | heading | icon | |
123 // +--------------------| | +--------------| | | 193 // +--------------------| | +--------------| | |
124 // | rating | | | rating | | | 194 // | rating | | | rating | | |
125 // +--------------------| | +--------------+ | | 195 // +--------------------| | +--------------+ | |
126 // | user_count | | | user_count | | | 196 // | user_count | | | user_count | | |
127 // +--------------------| | +--------------| | | 197 // +--------------------| | +--------------| | |
128 // | store_link | | | store_link | | | 198 // | store_link | | | store_link | | |
129 // +--------------------+------+ +--------------+------+ | 199 // +--------------------+------+ +--------------+------+ |
130 // | separator | | 200 // | separator | |
131 // +--------------------+------+ | 201 // +--------------------+------+ |
132 // | permissions_header | | | 202 // | permissions_header | | |
133 // +--------------------+------+ | 203 // +--------------------+------+ |
134 // | permission1 | | | 204 // | permission1 | | |
135 // +--------------------+------+ | 205 // +--------------------+------+ |
136 // | permission2 | | | 206 // | permission2 | | |
137 // +--------------------+------+ | 207 // +--------------------+------+ |
138 // | 208 // |
139 // Regular install | 209 // Regular install |
140 // w/ permissions no permissions | 210 // w/ permissions XOR oauth issues no permissions |
141 // +--------------------+------+ +--------------+------+ | 211 // +--------------------+------+ +--------------+------+ |
142 // | heading | icon | | heading | icon | | 212 // | heading | icon | | heading | icon | |
143 // +--------------------| | +--------------+------+ | 213 // +--------------------| | +--------------+------+ |
144 // | permissions_header | | | 214 // | permissions_header | | |
145 // +--------------------| | | 215 // +--------------------| | |
146 // | permission1 | | | 216 // | permission1 | | |
147 // +--------------------| | | 217 // +--------------------| | |
148 // | permission2 | | | 218 // | permission2 | | |
149 // +--------------------+------+ | 219 // +--------------------+------+ |
| 220 // |
| 221 // w/ permissions AND oauth issues |
| 222 // +--------------------+------+ |
| 223 // | heading | icon | |
| 224 // +--------------------| | |
| 225 // | permissions_header | | |
| 226 // +--------------------| | |
| 227 // | permission1 | | |
| 228 // +--------------------| | |
| 229 // | permission2 | | |
| 230 // +--------------------+------+ |
| 231 // | oauth header | |
| 232 // +---------------------------+ |
| 233 // | oauth issue 1 | |
| 234 // +---------------------------+ |
| 235 // | oauth issue 2 | |
| 236 // +---------------------------+ |
150 | 237 |
151 views::GridLayout* layout = views::GridLayout::CreatePanel(this); | 238 views::GridLayout* layout = views::GridLayout::CreatePanel(this); |
152 SetLayoutManager(layout); | 239 SetLayoutManager(layout); |
153 | 240 |
154 int column_set_id = 0; | 241 int column_set_id = 0; |
155 views::ColumnSet* column_set = layout->AddColumnSet(column_set_id); | 242 views::ColumnSet* column_set = layout->AddColumnSet(column_set_id); |
156 int left_column_width = prompt.GetPermissionCount() > 0 ? | 243 int left_column_width = prompt.GetPermissionCount() > 0 ? |
157 kPermissionsLeftColumnWidth : kNoPermissionsLeftColumnWidth; | 244 kPermissionsLeftColumnWidth : kNoPermissionsLeftColumnWidth; |
158 if (is_bundle_install()) | 245 if (is_bundle_install()) |
159 left_column_width = kBundleLeftColumnWidth; | 246 left_column_width = kBundleLeftColumnWidth; |
160 | 247 |
161 column_set->AddColumn(views::GridLayout::LEADING, | 248 column_set->AddColumn(views::GridLayout::LEADING, |
162 views::GridLayout::FILL, | 249 views::GridLayout::FILL, |
163 0, // no resizing | 250 0, // no resizing |
164 views::GridLayout::USE_PREF, | 251 views::GridLayout::USE_PREF, |
165 0, // no fixed with | 252 0, // no fixed width |
166 left_column_width); | 253 left_column_width); |
167 if (!is_bundle_install()) { | 254 if (!is_bundle_install()) { |
168 column_set->AddPaddingColumn(0, views::kPanelHorizMargin); | 255 column_set->AddPaddingColumn(0, views::kPanelHorizMargin); |
169 column_set->AddColumn(views::GridLayout::LEADING, | 256 column_set->AddColumn(views::GridLayout::LEADING, |
170 views::GridLayout::LEADING, | 257 views::GridLayout::LEADING, |
171 0, // no resizing | 258 0, // no resizing |
172 views::GridLayout::USE_PREF, | 259 views::GridLayout::USE_PREF, |
173 0, // no fixed width | 260 0, // no fixed width |
174 kIconSize); | 261 kIconSize); |
175 } | 262 } |
(...skipping 20 matching lines...) Expand all Loading... |
196 icon->SetHorizontalAlignment(views::ImageView::CENTER); | 283 icon->SetHorizontalAlignment(views::ImageView::CENTER); |
197 icon->SetVerticalAlignment(views::ImageView::CENTER); | 284 icon->SetVerticalAlignment(views::ImageView::CENTER); |
198 int icon_row_span = 1; | 285 int icon_row_span = 1; |
199 if (is_inline_install()) { | 286 if (is_inline_install()) { |
200 // Also span the rating, user_count and store_link rows. | 287 // Also span the rating, user_count and store_link rows. |
201 icon_row_span = 4; | 288 icon_row_span = 4; |
202 } else if (prompt.GetPermissionCount()) { | 289 } else if (prompt.GetPermissionCount()) { |
203 // Also span the permission header and each of the permission rows (all | 290 // Also span the permission header and each of the permission rows (all |
204 // have a padding row above it). | 291 // have a padding row above it). |
205 icon_row_span = 3 + prompt.GetPermissionCount() * 2; | 292 icon_row_span = 3 + prompt.GetPermissionCount() * 2; |
| 293 } else if (prompt.GetOAuthIssueCount()) { |
| 294 // Also span the permission header and each of the permission rows (all |
| 295 // have a padding row above it). |
| 296 icon_row_span = 3 + prompt.GetOAuthIssueCount() * 2; |
206 } | 297 } |
207 layout->AddView(icon, 1, icon_row_span); | 298 layout->AddView(icon, 1, icon_row_span); |
208 } | 299 } |
209 | 300 |
210 if (is_inline_install()) { | 301 if (is_inline_install()) { |
211 layout->StartRow(0, column_set_id); | 302 layout->StartRow(0, column_set_id); |
212 views::View* rating = new views::View(); | 303 views::View* rating = new views::View(); |
213 rating->SetLayoutManager(new views::BoxLayout( | 304 rating->SetLayoutManager(new views::BoxLayout( |
214 views::BoxLayout::kHorizontal, 0, 0, 0)); | 305 views::BoxLayout::kHorizontal, 0, 0, 0)); |
215 layout->AddView(rating); | 306 layout->AddView(rating); |
(...skipping 23 matching lines...) Expand all Loading... |
239 | 330 |
240 if (is_bundle_install()) { | 331 if (is_bundle_install()) { |
241 BundleInstaller::ItemList items = prompt_.bundle()->GetItemsWithState( | 332 BundleInstaller::ItemList items = prompt_.bundle()->GetItemsWithState( |
242 BundleInstaller::Item::STATE_PENDING); | 333 BundleInstaller::Item::STATE_PENDING); |
243 for (size_t i = 0; i < items.size(); ++i) { | 334 for (size_t i = 0; i < items.size(); ++i) { |
244 string16 extension_name = UTF8ToUTF16(items[i].localized_name); | 335 string16 extension_name = UTF8ToUTF16(items[i].localized_name); |
245 base::i18n::AdjustStringForLocaleDirection(&extension_name); | 336 base::i18n::AdjustStringForLocaleDirection(&extension_name); |
246 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | 337 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); |
247 layout->StartRow(0, column_set_id); | 338 layout->StartRow(0, column_set_id); |
248 views::Label* extension_label = new views::Label( | 339 views::Label* extension_label = new views::Label( |
249 l10n_util::GetStringFUTF16( | 340 PrepareForDisplay(extension_name, true)); |
250 IDS_EXTENSION_PERMISSION_LINE, extension_name)); | |
251 extension_label->SetMultiLine(true); | 341 extension_label->SetMultiLine(true); |
252 extension_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 342 extension_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
253 extension_label->SizeToFit(left_column_width); | 343 extension_label->SizeToFit(left_column_width); |
254 layout->AddView(extension_label); | 344 layout->AddView(extension_label); |
255 } | 345 } |
256 } | 346 } |
257 | 347 |
258 if (prompt.GetPermissionCount()) { | 348 if (prompt.GetPermissionCount()) { |
259 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | 349 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); |
260 | 350 |
(...skipping 26 matching lines...) Expand all Loading... |
287 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | 377 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); |
288 layout->StartRow(0, column_set_id); | 378 layout->StartRow(0, column_set_id); |
289 views::Label* permission_label = new views::Label( | 379 views::Label* permission_label = new views::Label( |
290 prompt.GetPermission(i)); | 380 prompt.GetPermission(i)); |
291 permission_label->SetMultiLine(true); | 381 permission_label->SetMultiLine(true); |
292 permission_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 382 permission_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
293 permission_label->SizeToFit(left_column_width); | 383 permission_label->SizeToFit(left_column_width); |
294 layout->AddView(permission_label); | 384 layout->AddView(permission_label); |
295 } | 385 } |
296 } | 386 } |
| 387 |
| 388 if (prompt.GetOAuthIssueCount()) { |
| 389 // Slide in under the permissions; stretch all the way to the right of the |
| 390 // dialog. |
| 391 int space_for_oauth = left_column_width; |
| 392 if (prompt.GetPermissionCount()) { |
| 393 space_for_oauth += kIconSize; |
| 394 column_set = layout->AddColumnSet(++column_set_id); |
| 395 column_set->AddColumn(views::GridLayout::FILL, |
| 396 views::GridLayout::FILL, |
| 397 1, |
| 398 views::GridLayout::USE_PREF, |
| 399 0, // no fixed width |
| 400 space_for_oauth); |
| 401 } |
| 402 |
| 403 layout->StartRowWithPadding(0, column_set_id, |
| 404 0, views::kRelatedControlVerticalSpacing); |
| 405 views::Label* oauth_header = new views::Label(prompt.GetOAuthHeading()); |
| 406 oauth_header->SetMultiLine(true); |
| 407 oauth_header->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
| 408 oauth_header->SizeToFit(left_column_width); |
| 409 layout->AddView(oauth_header); |
| 410 |
| 411 for (size_t i = 0; i < prompt.GetOAuthIssueCount(); ++i) { |
| 412 layout->StartRowWithPadding( |
| 413 0, column_set_id, |
| 414 0, views::kRelatedControlVerticalSpacing); |
| 415 |
| 416 IssueAdviceView* issue_advice_view = |
| 417 new IssueAdviceView(this, prompt.GetOAuthIssue(i), space_for_oauth); |
| 418 layout->AddView(issue_advice_view); |
| 419 } |
| 420 } |
297 } | 421 } |
298 | 422 |
299 ExtensionInstallDialogView::~ExtensionInstallDialogView() { | 423 ExtensionInstallDialogView::~ExtensionInstallDialogView() { |
300 } | 424 } |
301 | 425 |
| 426 void ExtensionInstallDialogView::SizeToContents() { |
| 427 GetWidget()->SetSize(GetWidget()->non_client_view()->GetPreferredSize()); |
| 428 } |
| 429 |
302 string16 ExtensionInstallDialogView::GetDialogButtonLabel( | 430 string16 ExtensionInstallDialogView::GetDialogButtonLabel( |
303 ui::DialogButton button) const { | 431 ui::DialogButton button) const { |
304 switch (button) { | 432 switch (button) { |
305 case ui::DIALOG_BUTTON_OK: | 433 case ui::DIALOG_BUTTON_OK: |
306 return prompt_.GetAcceptButtonLabel(); | 434 return prompt_.GetAcceptButtonLabel(); |
307 case ui::DIALOG_BUTTON_CANCEL: | 435 case ui::DIALOG_BUTTON_CANCEL: |
308 return prompt_.HasAbortButtonLabel() ? | 436 return prompt_.HasAbortButtonLabel() ? |
309 prompt_.GetAbortButtonLabel() : | 437 prompt_.GetAbortButtonLabel() : |
310 l10n_util::GetStringUTF16(IDS_CANCEL); | 438 l10n_util::GetStringUTF16(IDS_CANCEL); |
311 default: | 439 default: |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 | 481 |
354 void ShowExtensionInstallDialogImpl( | 482 void ShowExtensionInstallDialogImpl( |
355 gfx::NativeWindow parent, | 483 gfx::NativeWindow parent, |
356 content::PageNavigator* navigator, | 484 content::PageNavigator* navigator, |
357 ExtensionInstallPrompt::Delegate* delegate, | 485 ExtensionInstallPrompt::Delegate* delegate, |
358 const ExtensionInstallPrompt::Prompt& prompt) { | 486 const ExtensionInstallPrompt::Prompt& prompt) { |
359 views::Widget::CreateWindowWithParent( | 487 views::Widget::CreateWindowWithParent( |
360 new ExtensionInstallDialogView(navigator, delegate, prompt), | 488 new ExtensionInstallDialogView(navigator, delegate, prompt), |
361 parent)->Show(); | 489 parent)->Show(); |
362 } | 490 } |
| 491 |
| 492 // IssueAdviceView::DetailsView ------------------------------------------------ |
| 493 |
| 494 IssueAdviceView::DetailsView::DetailsView(int horizontal_space) |
| 495 : layout_(new views::GridLayout(this)), |
| 496 state_(0) { |
| 497 SetLayoutManager(layout_); |
| 498 views::ColumnSet* column_set = layout_->AddColumnSet(0); |
| 499 column_set->AddColumn(views::GridLayout::LEADING, |
| 500 views::GridLayout::LEADING, |
| 501 0, |
| 502 views::GridLayout::FIXED, |
| 503 horizontal_space, |
| 504 0); |
| 505 } |
| 506 |
| 507 void IssueAdviceView::DetailsView::AddDetail(const string16& detail) { |
| 508 layout_->StartRowWithPadding(0, 0, |
| 509 0, views::kRelatedControlSmallVerticalSpacing); |
| 510 views::Label* detail_label = |
| 511 new views::Label(PrepareForDisplay(detail, true)); |
| 512 detail_label->SetMultiLine(true); |
| 513 detail_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
| 514 layout_->AddView(detail_label); |
| 515 } |
| 516 |
| 517 gfx::Size IssueAdviceView::DetailsView::GetPreferredSize() { |
| 518 gfx::Size size = views::View::GetPreferredSize(); |
| 519 return gfx::Size(size.width(), size.height() * state_); |
| 520 } |
| 521 |
| 522 void IssueAdviceView::DetailsView::AnimateToState(double state) { |
| 523 state_ = state; |
| 524 PreferredSizeChanged(); |
| 525 SchedulePaint(); |
| 526 } |
| 527 |
| 528 // IssueAdviceView ------------------------------------------------------------- |
| 529 |
| 530 IssueAdviceView::IssueAdviceView(ExtensionInstallDialogView* owner, |
| 531 const IssueAdviceInfoEntry& issue_advice, |
| 532 int horizontal_space) |
| 533 : owner_(owner), |
| 534 details_view_(NULL), |
| 535 arrow_view_(NULL), |
| 536 slide_animation_(this) { |
| 537 // TODO(estade): replace this with a more appropriate image. |
| 538 const gfx::ImageSkia& image = *ui::ResourceBundle::GetSharedInstance(). |
| 539 GetImageSkiaNamed(IDR_OMNIBOX_TTS); |
| 540 |
| 541 views::GridLayout* layout = new views::GridLayout(this); |
| 542 SetLayoutManager(layout); |
| 543 int column_set_id = 0; |
| 544 views::ColumnSet* column_set = layout->AddColumnSet(column_set_id); |
| 545 if (!issue_advice.details.empty()) { |
| 546 column_set->AddColumn(views::GridLayout::LEADING, |
| 547 views::GridLayout::LEADING, |
| 548 0, |
| 549 views::GridLayout::FIXED, |
| 550 image.width(), |
| 551 0); |
| 552 horizontal_space -= image.width(); |
| 553 details_view_ = new DetailsView(horizontal_space); |
| 554 } |
| 555 column_set->AddColumn(views::GridLayout::LEADING, |
| 556 views::GridLayout::FILL, |
| 557 0, |
| 558 views::GridLayout::FIXED, |
| 559 horizontal_space, |
| 560 0); |
| 561 layout->StartRow(0, column_set_id); |
| 562 |
| 563 if (details_view_) { |
| 564 arrow_view_ = new views::ImageView(); |
| 565 arrow_view_->SetImage(image); |
| 566 arrow_view_->SetVerticalAlignment(views::ImageView::CENTER); |
| 567 layout->AddView(arrow_view_); |
| 568 } |
| 569 |
| 570 views::Label* description_label = |
| 571 new views::Label(PrepareForDisplay(issue_advice.description, |
| 572 !details_view_)); |
| 573 description_label->SetMultiLine(true); |
| 574 description_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
| 575 description_label->SizeToFit(horizontal_space); |
| 576 layout->AddView(description_label); |
| 577 |
| 578 if (!details_view_) |
| 579 return; |
| 580 |
| 581 layout->StartRow(0, column_set_id); |
| 582 layout->SkipColumns(1); |
| 583 layout->AddView(details_view_); |
| 584 |
| 585 for (size_t i = 0; i < issue_advice.details.size(); ++i) |
| 586 details_view_->AddDetail(issue_advice.details[i]); |
| 587 } |
| 588 |
| 589 bool IssueAdviceView::OnMousePressed(const views::MouseEvent& event) { |
| 590 return details_view_ && event.IsLeftMouseButton(); |
| 591 } |
| 592 |
| 593 void IssueAdviceView::OnMouseReleased(const views::MouseEvent& event) { |
| 594 if (slide_animation_.IsShowing()) |
| 595 slide_animation_.Hide(); |
| 596 else |
| 597 slide_animation_.Show(); |
| 598 } |
| 599 |
| 600 void IssueAdviceView::AnimationProgressed(const ui::Animation* animation) { |
| 601 DCHECK_EQ(animation, &slide_animation_); |
| 602 |
| 603 if (details_view_) |
| 604 details_view_->AnimateToState(animation->GetCurrentValue()); |
| 605 |
| 606 if (arrow_view_) { |
| 607 ui::Transform rotate; |
| 608 if (animation->GetCurrentValue() != 0.0) { |
| 609 rotate.SetTranslate(-arrow_view_->width() / 2.0, |
| 610 -arrow_view_->height() / 2.0); |
| 611 // TODO(estade): for some reason there are rendering errors at 90 degrees. |
| 612 // Figure out why. |
| 613 rotate.ConcatRotate(animation->GetCurrentValue() * 89); |
| 614 rotate.ConcatTranslate(arrow_view_->width() / 2.0, |
| 615 arrow_view_->height() / 2.0); |
| 616 } |
| 617 arrow_view_->SetTransform(rotate); |
| 618 } |
| 619 } |
| 620 |
| 621 void IssueAdviceView::ChildPreferredSizeChanged(views::View* child) { |
| 622 owner_->SizeToContents(); |
| 623 } |
OLD | NEW |