| 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/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/i18n/rtl.h" | 10 #include "base/i18n/rtl.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "grit/chromium_strings.h" | 22 #include "grit/chromium_strings.h" |
| 23 #include "grit/generated_resources.h" | 23 #include "grit/generated_resources.h" |
| 24 #include "grit/google_chrome_strings.h" | 24 #include "grit/google_chrome_strings.h" |
| 25 #include "grit/theme_resources.h" | 25 #include "grit/theme_resources.h" |
| 26 #include "ui/base/animation/animation_delegate.h" | 26 #include "ui/base/animation/animation_delegate.h" |
| 27 #include "ui/base/animation/slide_animation.h" | 27 #include "ui/base/animation/slide_animation.h" |
| 28 #include "ui/base/l10n/l10n_util.h" | 28 #include "ui/base/l10n/l10n_util.h" |
| 29 #include "ui/base/resource/resource_bundle.h" | 29 #include "ui/base/resource/resource_bundle.h" |
| 30 #include "ui/gfx/transform.h" | 30 #include "ui/gfx/transform.h" |
| 31 #include "ui/views/border.h" | 31 #include "ui/views/border.h" |
| 32 #include "ui/views/controls/button/image_button.h" |
| 32 #include "ui/views/controls/image_view.h" | 33 #include "ui/views/controls/image_view.h" |
| 33 #include "ui/views/controls/label.h" | 34 #include "ui/views/controls/label.h" |
| 34 #include "ui/views/controls/link.h" | 35 #include "ui/views/controls/link.h" |
| 35 #include "ui/views/controls/link_listener.h" | 36 #include "ui/views/controls/link_listener.h" |
| 36 #include "ui/views/controls/scroll_view.h" | 37 #include "ui/views/controls/scroll_view.h" |
| 37 #include "ui/views/controls/separator.h" | 38 #include "ui/views/controls/separator.h" |
| 38 #include "ui/views/layout/box_layout.h" | 39 #include "ui/views/layout/box_layout.h" |
| 39 #include "ui/views/layout/grid_layout.h" | 40 #include "ui/views/layout/grid_layout.h" |
| 40 #include "ui/views/layout/layout_constants.h" | 41 #include "ui/views/layout/layout_constants.h" |
| 41 #include "ui/views/view.h" | 42 #include "ui/views/view.h" |
| 42 #include "ui/views/widget/widget.h" | 43 #include "ui/views/widget/widget.h" |
| 43 #include "ui/views/window/dialog_delegate.h" | 44 #include "ui/views/window/dialog_delegate.h" |
| 44 | 45 |
| 45 using content::OpenURLParams; | 46 using content::OpenURLParams; |
| 46 using content::Referrer; | 47 using content::Referrer; |
| 47 using extensions::BundleInstaller; | 48 using extensions::BundleInstaller; |
| 48 | 49 |
| 49 namespace { | 50 namespace { |
| 50 | 51 |
| 51 // Size of extension icon in top left of dialog. | 52 // Size of extension icon in top left of dialog. |
| 52 const int kIconSize = 69; | 53 const int kIconSize = 69; |
| 53 | 54 |
| 55 // The dialog width. |
| 56 const int kDialogWidth = 385; |
| 57 |
| 58 // The dialog will resize based on its content, but this sets a maximum height |
| 59 // before overflowing a scrollbar. |
| 60 const int kDialogMaxHeight = 300; |
| 61 |
| 54 // Width of the left column of the dialog when the extension requests | 62 // Width of the left column of the dialog when the extension requests |
| 55 // permissions. | 63 // permissions. |
| 56 const int kPermissionsLeftColumnWidth = 250; | 64 const int kPermissionsLeftColumnWidth = 250; |
| 57 | 65 |
| 58 // Width of the left column of the dialog when the extension requests no | 66 // Width of the left column of the dialog when the extension requests no |
| 59 // permissions. | 67 // permissions. |
| 60 const int kNoPermissionsLeftColumnWidth = 200; | 68 const int kNoPermissionsLeftColumnWidth = 200; |
| 61 | 69 |
| 62 // Width of the left column for bundle install prompts. There's only one column | 70 // Width of the left column for bundle install prompts. There's only one column |
| 63 // in this case, so make it wider than normal. | 71 // in this case, so make it wider than normal. |
| 64 const int kBundleLeftColumnWidth = 300; | 72 const int kBundleLeftColumnWidth = 300; |
| 65 | 73 |
| 66 // Width of the left column for external install prompts. The text is long in | 74 // Width of the left column for external install prompts. The text is long in |
| 67 // this case, so make it wider than normal. | 75 // this case, so make it wider than normal. |
| 68 const int kExternalInstallLeftColumnWidth = 350; | 76 const int kExternalInstallLeftColumnWidth = 350; |
| 69 | 77 |
| 70 // Maximum height of the retained files view. | 78 // Maximum height of the retained files view. |
| 71 const int kMaxRetainedFilesHeight = 100; | 79 const int kMaxRetainedFilesHeight = 100; |
| 72 | 80 |
| 81 typedef std::vector<string16> PermissionDetails; |
| 82 |
| 73 void AddResourceIcon(const gfx::ImageSkia* skia_image, void* data) { | 83 void AddResourceIcon(const gfx::ImageSkia* skia_image, void* data) { |
| 74 views::View* parent = static_cast<views::View*>(data); | 84 views::View* parent = static_cast<views::View*>(data); |
| 75 views::ImageView* image_view = new views::ImageView(); | 85 views::ImageView* image_view = new views::ImageView(); |
| 76 image_view->SetImage(*skia_image); | 86 image_view->SetImage(*skia_image); |
| 77 parent->AddChildView(image_view); | 87 parent->AddChildView(image_view); |
| 78 } | 88 } |
| 79 | 89 |
| 80 // Creates a string for displaying |message| to the user. If it has to look | 90 // Creates a string for displaying |message| to the user. If it has to look |
| 81 // like a entry in a bullet point list, one is added. | 91 // like a entry in a bullet point list, one is added. |
| 82 string16 PrepareForDisplay(const string16& message, bool bullet_point) { | 92 string16 PrepareForDisplay(const string16& message, bool bullet_point) { |
| 83 return bullet_point ? l10n_util::GetStringFUTF16( | 93 return bullet_point ? l10n_util::GetStringFUTF16( |
| 84 IDS_EXTENSION_PERMISSION_LINE, | 94 IDS_EXTENSION_PERMISSION_LINE, |
| 85 message) : message; | 95 message) : message; |
| 86 } | 96 } |
| 87 | 97 |
| 88 // Implements the extension installation dialog for TOOLKIT_VIEWS. | 98 // Implements the extension installation dialog for TOOLKIT_VIEWS. |
| 89 class ExtensionInstallDialogView : public views::DialogDelegateView, | 99 class ExtensionInstallDialogView : public views::DialogDelegateView, |
| 90 public views::LinkListener { | 100 public views::LinkListener { |
| 91 public: | 101 public: |
| 92 ExtensionInstallDialogView(content::PageNavigator* navigator, | 102 ExtensionInstallDialogView(content::PageNavigator* navigator, |
| 93 ExtensionInstallPrompt::Delegate* delegate, | 103 ExtensionInstallPrompt::Delegate* delegate, |
| 94 const ExtensionInstallPrompt::Prompt& prompt); | 104 const ExtensionInstallPrompt::Prompt& prompt); |
| 95 virtual ~ExtensionInstallDialogView(); | 105 virtual ~ExtensionInstallDialogView(); |
| 96 | 106 |
| 97 // Changes the size of the containing widget to match the preferred size | 107 // Called when one of the child elements has expanded/collapsed. |
| 98 // of this dialog. | 108 void ContentsChanged(); |
| 99 void SizeToContents(); | |
| 100 | 109 |
| 101 private: | 110 private: |
| 102 // views::DialogDelegateView: | 111 // views::DialogDelegateView: |
| 103 virtual int GetDialogButtons() const OVERRIDE; | 112 virtual int GetDialogButtons() const OVERRIDE; |
| 104 virtual string16 GetDialogButtonLabel(ui::DialogButton button) const OVERRIDE; | 113 virtual string16 GetDialogButtonLabel(ui::DialogButton button) const OVERRIDE; |
| 105 virtual int GetDefaultDialogButton() const OVERRIDE; | 114 virtual int GetDefaultDialogButton() const OVERRIDE; |
| 106 virtual bool Cancel() OVERRIDE; | 115 virtual bool Cancel() OVERRIDE; |
| 107 virtual bool Accept() OVERRIDE; | 116 virtual bool Accept() OVERRIDE; |
| 108 | |
| 109 // views::WidgetDelegate: | |
| 110 virtual ui::ModalType GetModalType() const OVERRIDE; | 117 virtual ui::ModalType GetModalType() const OVERRIDE; |
| 111 virtual string16 GetWindowTitle() const OVERRIDE; | 118 virtual string16 GetWindowTitle() const OVERRIDE; |
| 119 virtual void Layout() OVERRIDE; |
| 120 virtual gfx::Size GetPreferredSize() OVERRIDE; |
| 112 | 121 |
| 113 // views::LinkListener: | 122 // views::LinkListener: |
| 114 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; | 123 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; |
| 115 | 124 |
| 116 bool is_inline_install() const { | 125 bool is_inline_install() const { |
| 117 return prompt_.type() == ExtensionInstallPrompt::INLINE_INSTALL_PROMPT; | 126 return prompt_.type() == ExtensionInstallPrompt::INLINE_INSTALL_PROMPT; |
| 118 } | 127 } |
| 119 | 128 |
| 120 bool is_bundle_install() const { | 129 bool is_bundle_install() const { |
| 121 return prompt_.type() == ExtensionInstallPrompt::BUNDLE_INSTALL_PROMPT; | 130 return prompt_.type() == ExtensionInstallPrompt::BUNDLE_INSTALL_PROMPT; |
| 122 } | 131 } |
| 123 | 132 |
| 124 bool is_external_install() const { | 133 bool is_external_install() const { |
| 125 return prompt_.type() == ExtensionInstallPrompt::EXTERNAL_INSTALL_PROMPT; | 134 return prompt_.type() == ExtensionInstallPrompt::EXTERNAL_INSTALL_PROMPT; |
| 126 } | 135 } |
| 127 | 136 |
| 128 content::PageNavigator* navigator_; | 137 content::PageNavigator* navigator_; |
| 129 ExtensionInstallPrompt::Delegate* delegate_; | 138 ExtensionInstallPrompt::Delegate* delegate_; |
| 130 ExtensionInstallPrompt::Prompt prompt_; | 139 ExtensionInstallPrompt::Prompt prompt_; |
| 131 | 140 |
| 141 // The scroll view containing all the details for the dialog (including all |
| 142 // collapsible/expandable sections). |
| 143 views::ScrollView* scroll_view_; |
| 144 |
| 145 // The container view for the scroll view. |
| 146 views::View* scrollable_; |
| 147 |
| 148 // The preferred size of the dialog. |
| 149 gfx::Size dialog_size_; |
| 150 |
| 132 DISALLOW_COPY_AND_ASSIGN(ExtensionInstallDialogView); | 151 DISALLOW_COPY_AND_ASSIGN(ExtensionInstallDialogView); |
| 133 }; | 152 }; |
| 134 | 153 |
| 135 // A view to display a single IssueAdviceInfoEntry. | 154 // A view to display text with an expandable details section. |
| 136 class IssueAdviceView : public views::View, | 155 class ExpandableContainerView : public views::View, |
| 137 public ui::AnimationDelegate { | 156 public views::ButtonListener, |
| 157 public views::LinkListener, |
| 158 public ui::AnimationDelegate { |
| 138 public: | 159 public: |
| 139 IssueAdviceView(ExtensionInstallDialogView* owner, | 160 ExpandableContainerView(ExtensionInstallDialogView* owner, |
| 140 const IssueAdviceInfoEntry& issue_advice, | 161 const string16& description, |
| 141 int horizontal_space); | 162 const PermissionDetails& details, |
| 142 virtual ~IssueAdviceView() {} | 163 int horizontal_space, |
| 164 bool show_bullets); |
| 165 virtual ~ExpandableContainerView(); |
| 143 | 166 |
| 144 // Implementation of views::View: | 167 // views::View: |
| 145 virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; | |
| 146 virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE; | |
| 147 virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE; | 168 virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE; |
| 148 | 169 |
| 149 // Implementation of ui::AnimationDelegate: | 170 // views::ButtonListener: |
| 171 virtual void ButtonPressed(views::Button* sender, |
| 172 const ui::Event& event) OVERRIDE; |
| 173 |
| 174 // views::LinkListener: |
| 175 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; |
| 176 |
| 177 // ui::AnimationDelegate: |
| 150 virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE; | 178 virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE; |
| 179 virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE; |
| 151 | 180 |
| 152 private: | 181 private: |
| 153 // A view which displays all the details of an IssueAdviceInfoEntry. | 182 // A view which displays all the details of an IssueAdviceInfoEntry. |
| 154 class DetailsView : public views::View { | 183 class DetailsView : public views::View { |
| 155 public: | 184 public: |
| 156 explicit DetailsView(int horizontal_space); | 185 explicit DetailsView(int horizontal_space, bool show_bullets); |
| 157 virtual ~DetailsView() {} | 186 virtual ~DetailsView() {} |
| 158 | 187 |
| 159 // Implementation of views::View: | 188 // views::View: |
| 160 virtual gfx::Size GetPreferredSize() OVERRIDE; | 189 virtual gfx::Size GetPreferredSize() OVERRIDE; |
| 161 | 190 |
| 162 void AddDetail(const string16& detail); | 191 void AddDetail(const string16& detail); |
| 163 | 192 |
| 164 // Animates this to be a height proportional to |state|. | 193 // Animates this to be a height proportional to |state|. |
| 165 void AnimateToState(double state); | 194 void AnimateToState(double state); |
| 166 | 195 |
| 167 private: | 196 private: |
| 168 views::GridLayout* layout_; | 197 views::GridLayout* layout_; |
| 169 double state_; | 198 double state_; |
| 170 | 199 |
| 200 // Whether to show bullets in front of each item in the details. |
| 201 bool show_bullets_; |
| 202 |
| 171 DISALLOW_COPY_AND_ASSIGN(DetailsView); | 203 DISALLOW_COPY_AND_ASSIGN(DetailsView); |
| 172 }; | 204 }; |
| 173 | 205 |
| 206 // Expand/Collapse the detail section for this ExpandableContainerView. |
| 207 void ToggleDetailLevel(); |
| 208 |
| 174 // The dialog that owns |this|. It's also an ancestor in the View hierarchy. | 209 // The dialog that owns |this|. It's also an ancestor in the View hierarchy. |
| 175 ExtensionInstallDialogView* owner_; | 210 ExtensionInstallDialogView* owner_; |
| 176 | 211 |
| 177 // A view for showing |issue_advice.details|. | 212 // A view for showing |issue_advice.details|. |
| 178 DetailsView* details_view_; | 213 DetailsView* details_view_; |
| 179 | 214 |
| 180 // The '>' zippy control. | 215 // The '>' zippy control. |
| 181 views::ImageView* arrow_view_; | 216 views::ImageView* arrow_view_; |
| 182 | 217 |
| 183 ui::SlideAnimation slide_animation_; | 218 ui::SlideAnimation slide_animation_; |
| 184 | 219 |
| 185 DISALLOW_COPY_AND_ASSIGN(IssueAdviceView); | 220 // The 'more details' link shown under the heading (changes to 'hide details' |
| 221 // when the details section is expanded). |
| 222 views::Link* more_details_; |
| 223 |
| 224 // The up/down arrow next to the 'more detail' link (points up/down depending |
| 225 // on whether the details section is expanded). |
| 226 views::ImageButton* arrow_toggle_; |
| 227 |
| 228 // Whether the details section is expanded. |
| 229 bool expanded_; |
| 230 |
| 231 DISALLOW_COPY_AND_ASSIGN(ExpandableContainerView); |
| 186 }; | 232 }; |
| 187 | 233 |
| 188 void ShowExtensionInstallDialogImpl( | 234 void ShowExtensionInstallDialogImpl( |
| 189 const ExtensionInstallPrompt::ShowParams& show_params, | 235 const ExtensionInstallPrompt::ShowParams& show_params, |
| 190 ExtensionInstallPrompt::Delegate* delegate, | 236 ExtensionInstallPrompt::Delegate* delegate, |
| 191 const ExtensionInstallPrompt::Prompt& prompt) { | 237 const ExtensionInstallPrompt::Prompt& prompt) { |
| 192 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 238 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 193 CreateBrowserModalDialogViews( | 239 CreateBrowserModalDialogViews( |
| 194 new ExtensionInstallDialogView(show_params.navigator, delegate, prompt), | 240 new ExtensionInstallDialogView(show_params.navigator, delegate, prompt), |
| 195 show_params.parent_window)->Show(); | 241 show_params.parent_window)->Show(); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 // +--------------------| | | 327 // +--------------------| | |
| 282 // | permission2 | | | 328 // | permission2 | | |
| 283 // +--------------------+------+ | 329 // +--------------------+------+ |
| 284 // | oauth header | | 330 // | oauth header | |
| 285 // +---------------------------+ | 331 // +---------------------------+ |
| 286 // | oauth issue 1 | | 332 // | oauth issue 1 | |
| 287 // +---------------------------+ | 333 // +---------------------------+ |
| 288 // | oauth issue 2 | | 334 // | oauth issue 2 | |
| 289 // +---------------------------+ | 335 // +---------------------------+ |
| 290 | 336 |
| 291 views::GridLayout* layout = views::GridLayout::CreatePanel(this); | 337 scroll_view_ = new views::ScrollView(); |
| 292 SetLayoutManager(layout); | 338 AddChildView(scroll_view_); |
| 339 scrollable_ = new views::View(); |
| 340 scroll_view_->SetContents(scrollable_); |
| 341 |
| 342 views::GridLayout* layout = views::GridLayout::CreatePanel(scrollable_); |
| 343 scrollable_->SetLayoutManager(layout); |
| 293 | 344 |
| 294 int column_set_id = 0; | 345 int column_set_id = 0; |
| 295 views::ColumnSet* column_set = layout->AddColumnSet(column_set_id); | 346 views::ColumnSet* column_set = layout->AddColumnSet(column_set_id); |
| 296 int left_column_width = | 347 int left_column_width = |
| 297 (prompt.ShouldShowPermissions() + prompt.GetOAuthIssueCount() + | 348 (prompt.ShouldShowPermissions() + prompt.GetOAuthIssueCount() + |
| 298 prompt.GetRetainedFileCount()) > 0 ? | 349 prompt.GetRetainedFileCount()) > 0 ? |
| 299 kPermissionsLeftColumnWidth : kNoPermissionsLeftColumnWidth; | 350 kPermissionsLeftColumnWidth : kNoPermissionsLeftColumnWidth; |
| 300 if (is_bundle_install()) | 351 if (is_bundle_install()) |
| 301 left_column_width = kBundleLeftColumnWidth; | 352 left_column_width = kBundleLeftColumnWidth; |
| 302 if (is_external_install()) | 353 if (is_external_install()) |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 } else { | 404 } else { |
| 354 // This is the 'no special permissions' case, so span the line we add | 405 // This is the 'no special permissions' case, so span the line we add |
| 355 // (without a header) saying the extension has no special privileges. | 406 // (without a header) saying the extension has no special privileges. |
| 356 icon_row_span = 4; | 407 icon_row_span = 4; |
| 357 } | 408 } |
| 358 } else if (prompt.GetOAuthIssueCount()) { | 409 } else if (prompt.GetOAuthIssueCount()) { |
| 359 // Also span the permission header and each of the permission rows (all | 410 // Also span the permission header and each of the permission rows (all |
| 360 // have a padding row above it). | 411 // have a padding row above it). |
| 361 icon_row_span = 3 + prompt.GetOAuthIssueCount() * 2; | 412 icon_row_span = 3 + prompt.GetOAuthIssueCount() * 2; |
| 362 } else if (prompt.GetRetainedFileCount()) { | 413 } else if (prompt.GetRetainedFileCount()) { |
| 363 // Also span the permission header and each of the permission rows (all | 414 // Also span the permission header and the retained files container. |
| 364 // have a padding row above it). | 415 icon_row_span = 4; |
| 365 icon_row_span = 3 + prompt.GetRetainedFileCount() * 2; | |
| 366 } | 416 } |
| 367 layout->AddView(icon, 1, icon_row_span); | 417 layout->AddView(icon, 1, icon_row_span); |
| 368 } | 418 } |
| 369 | 419 |
| 370 if (is_inline_install()) { | 420 if (is_inline_install()) { |
| 371 layout->StartRow(0, column_set_id); | 421 layout->StartRow(0, column_set_id); |
| 372 views::View* rating = new views::View(); | 422 views::View* rating = new views::View(); |
| 373 rating->SetLayoutManager(new views::BoxLayout( | 423 rating->SetLayoutManager(new views::BoxLayout( |
| 374 views::BoxLayout::kHorizontal, 0, 0, 0)); | 424 views::BoxLayout::kHorizontal, 0, 0, 0)); |
| 375 layout->AddView(rating); | 425 layout->AddView(rating); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 390 | 440 |
| 391 layout->StartRow(0, column_set_id); | 441 layout->StartRow(0, column_set_id); |
| 392 views::Link* store_link = new views::Link( | 442 views::Link* store_link = new views::Link( |
| 393 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_STORE_LINK)); | 443 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_STORE_LINK)); |
| 394 store_link->SetFont(rb.GetFont(ui::ResourceBundle::SmallFont)); | 444 store_link->SetFont(rb.GetFont(ui::ResourceBundle::SmallFont)); |
| 395 store_link->set_listener(this); | 445 store_link->set_listener(this); |
| 396 layout->AddView(store_link); | 446 layout->AddView(store_link); |
| 397 } | 447 } |
| 398 | 448 |
| 399 if (is_bundle_install()) { | 449 if (is_bundle_install()) { |
| 400 BundleInstaller::ItemList items = prompt_.bundle()->GetItemsWithState( | 450 BundleInstaller::ItemList items = prompt.bundle()->GetItemsWithState( |
| 401 BundleInstaller::Item::STATE_PENDING); | 451 BundleInstaller::Item::STATE_PENDING); |
| 402 for (size_t i = 0; i < items.size(); ++i) { | 452 for (size_t i = 0; i < items.size(); ++i) { |
| 403 string16 extension_name = UTF8ToUTF16(items[i].localized_name); | 453 string16 extension_name = UTF8ToUTF16(items[i].localized_name); |
| 404 base::i18n::AdjustStringForLocaleDirection(&extension_name); | 454 base::i18n::AdjustStringForLocaleDirection(&extension_name); |
| 405 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | 455 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); |
| 406 layout->StartRow(0, column_set_id); | 456 layout->StartRow(0, column_set_id); |
| 407 views::Label* extension_label = new views::Label( | 457 views::Label* extension_label = new views::Label( |
| 408 PrepareForDisplay(extension_name, true)); | 458 PrepareForDisplay(extension_name, true)); |
| 409 extension_label->SetMultiLine(true); | 459 extension_label->SetMultiLine(true); |
| 410 extension_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 460 extension_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 | 493 |
| 444 for (size_t i = 0; i < prompt.GetPermissionCount(); ++i) { | 494 for (size_t i = 0; i < prompt.GetPermissionCount(); ++i) { |
| 445 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | 495 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); |
| 446 layout->StartRow(0, column_set_id); | 496 layout->StartRow(0, column_set_id); |
| 447 views::Label* permission_label = new views::Label(PrepareForDisplay( | 497 views::Label* permission_label = new views::Label(PrepareForDisplay( |
| 448 prompt.GetPermission(i), true)); | 498 prompt.GetPermission(i), true)); |
| 449 permission_label->SetMultiLine(true); | 499 permission_label->SetMultiLine(true); |
| 450 permission_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 500 permission_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 451 permission_label->SizeToFit(left_column_width); | 501 permission_label->SizeToFit(left_column_width); |
| 452 layout->AddView(permission_label); | 502 layout->AddView(permission_label); |
| 503 |
| 504 // If we have more details to provide, show them in collapsed form. |
| 505 if (!prompt.GetPermissionsDetails(i).empty()) { |
| 506 layout->StartRow(0, column_set_id); |
| 507 PermissionDetails details; |
| 508 details.push_back( |
| 509 PrepareForDisplay(prompt.GetPermissionsDetails(i), false)); |
| 510 ExpandableContainerView* details_container = |
| 511 new ExpandableContainerView( |
| 512 this, string16(), details, left_column_width, false); |
| 513 layout->AddView(details_container); |
| 514 } |
| 453 } | 515 } |
| 454 } else { | 516 } else { |
| 455 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | 517 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); |
| 456 layout->StartRow(0, column_set_id); | 518 layout->StartRow(0, column_set_id); |
| 457 views::Label* permission_label = new views::Label( | 519 views::Label* permission_label = new views::Label( |
| 458 l10n_util::GetStringUTF16(IDS_EXTENSION_NO_SPECIAL_PERMISSIONS)); | 520 l10n_util::GetStringUTF16(IDS_EXTENSION_NO_SPECIAL_PERMISSIONS)); |
| 459 permission_label->SetMultiLine(true); | 521 permission_label->SetMultiLine(true); |
| 460 permission_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 522 permission_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 461 permission_label->SizeToFit(left_column_width); | 523 permission_label->SizeToFit(left_column_width); |
| 462 layout->AddView(permission_label); | 524 layout->AddView(permission_label); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 486 oauth_header->SetMultiLine(true); | 548 oauth_header->SetMultiLine(true); |
| 487 oauth_header->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 549 oauth_header->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 488 oauth_header->SizeToFit(left_column_width); | 550 oauth_header->SizeToFit(left_column_width); |
| 489 layout->AddView(oauth_header); | 551 layout->AddView(oauth_header); |
| 490 | 552 |
| 491 for (size_t i = 0; i < prompt.GetOAuthIssueCount(); ++i) { | 553 for (size_t i = 0; i < prompt.GetOAuthIssueCount(); ++i) { |
| 492 layout->StartRowWithPadding( | 554 layout->StartRowWithPadding( |
| 493 0, column_set_id, | 555 0, column_set_id, |
| 494 0, views::kRelatedControlVerticalSpacing); | 556 0, views::kRelatedControlVerticalSpacing); |
| 495 | 557 |
| 496 IssueAdviceView* issue_advice_view = | 558 PermissionDetails details; |
| 497 new IssueAdviceView(this, prompt.GetOAuthIssue(i), space_for_oauth); | 559 const IssueAdviceInfoEntry& entry = prompt.GetOAuthIssue(i); |
| 560 for (size_t x = 0; x < entry.details.size(); ++x) |
| 561 details.push_back(entry.details[x]); |
| 562 ExpandableContainerView* issue_advice_view = |
| 563 new ExpandableContainerView( |
| 564 this, entry.description, details, space_for_oauth, false); |
| 498 layout->AddView(issue_advice_view); | 565 layout->AddView(issue_advice_view); |
| 499 } | 566 } |
| 500 } | 567 } |
| 501 if (prompt.GetRetainedFileCount()) { | 568 if (prompt.GetRetainedFileCount()) { |
| 502 // Slide in under the permissions or OAuth, if there are any. If there are | 569 // Slide in under the permissions or OAuth, if there are any. If there are |
| 503 // either, the retained files prompt stretches all the way to the right of | 570 // either, the retained files prompt stretches all the way to the right of |
| 504 // the dialog. If there are no permissions or OAuth, the retained files | 571 // the dialog. If there are no permissions or OAuth, the retained files |
| 505 // prompt just takes up the left column. | 572 // prompt just takes up the left column. |
| 506 int space_for_files = left_column_width; | 573 int space_for_files = left_column_width; |
| 507 if (prompt.GetPermissionCount() || prompt.GetOAuthIssueCount()) { | 574 if (prompt.GetPermissionCount() || prompt.GetOAuthIssueCount()) { |
| 508 space_for_files += kIconSize; | 575 space_for_files += kIconSize; |
| 509 column_set = layout->AddColumnSet(++column_set_id); | 576 column_set = layout->AddColumnSet(++column_set_id); |
| 510 column_set->AddColumn(views::GridLayout::FILL, | 577 column_set->AddColumn(views::GridLayout::FILL, |
| 511 views::GridLayout::FILL, | 578 views::GridLayout::FILL, |
| 512 1, | 579 1, |
| 513 views::GridLayout::USE_PREF, | 580 views::GridLayout::USE_PREF, |
| 514 0, // no fixed width | 581 0, // no fixed width |
| 515 space_for_files); | 582 space_for_files); |
| 516 } | 583 } |
| 517 | 584 |
| 518 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | 585 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); |
| 519 | 586 |
| 520 layout->StartRow(0, column_set_id); | 587 layout->StartRow(0, column_set_id); |
| 521 views::Label* retained_files_header = NULL; | 588 views::Label* retained_files_header = NULL; |
| 522 retained_files_header = new views::Label(prompt.GetRetainedFilesHeading()); | 589 retained_files_header = |
| 590 new views::Label(prompt.GetRetainedFilesHeadingWithCount()); |
| 523 retained_files_header->SetMultiLine(true); | 591 retained_files_header->SetMultiLine(true); |
| 524 retained_files_header->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 592 retained_files_header->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 525 retained_files_header->SizeToFit(space_for_files); | 593 retained_files_header->SizeToFit(space_for_files); |
| 526 layout->AddView(retained_files_header); | 594 layout->AddView(retained_files_header); |
| 527 | 595 |
| 528 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
| 529 layout->StartRow(0, column_set_id); | 596 layout->StartRow(0, column_set_id); |
| 530 views::View* files_view = new views::View(); | 597 PermissionDetails details; |
| 531 files_view->SetLayoutManager(new views::BoxLayout( | 598 for (size_t i = 0; i < prompt.GetRetainedFileCount(); ++i) |
| 532 views::BoxLayout::kVertical, | 599 details.push_back(prompt.GetRetainedFile(i)); |
| 533 views::kRelatedControlHorizontalSpacing, | 600 ExpandableContainerView* issue_advice_view = |
| 534 0, | 601 new ExpandableContainerView( |
| 535 0)); | 602 this, string16(), details, space_for_files, false); |
| 536 for (size_t i = 0; i < prompt.GetRetainedFileCount(); ++i) { | 603 layout->AddView(issue_advice_view); |
| 537 views::Label* retained_file_label = new views::Label(PrepareForDisplay( | |
| 538 prompt.GetRetainedFile(i), true)); | |
| 539 retained_file_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
| 540 files_view->AddChildView(retained_file_label); | |
| 541 } | |
| 542 views::ScrollView* scroll_view = | |
| 543 new MaxSizeScrollView(kMaxRetainedFilesHeight, space_for_files); | |
| 544 scroll_view->SetContents(files_view); | |
| 545 layout->AddView(scroll_view); | |
| 546 } | 604 } |
| 605 |
| 606 gfx::Size scrollable_size = scrollable_->GetPreferredSize(); |
| 607 scrollable_->SetBoundsRect(gfx::Rect(scrollable_size)); |
| 608 dialog_size_ = gfx::Size( |
| 609 kDialogWidth, |
| 610 std::min(scrollable_size.height(), kDialogMaxHeight)); |
| 547 } | 611 } |
| 548 | 612 |
| 549 ExtensionInstallDialogView::~ExtensionInstallDialogView() {} | 613 ExtensionInstallDialogView::~ExtensionInstallDialogView() {} |
| 550 | 614 |
| 551 void ExtensionInstallDialogView::SizeToContents() { | 615 void ExtensionInstallDialogView::ContentsChanged() { |
| 552 GetWidget()->SetSize(GetWidget()->non_client_view()->GetPreferredSize()); | 616 Layout(); |
| 553 } | 617 } |
| 554 | 618 |
| 555 int ExtensionInstallDialogView::GetDialogButtons() const { | 619 int ExtensionInstallDialogView::GetDialogButtons() const { |
| 556 int buttons = prompt_.GetDialogButtons(); | 620 int buttons = prompt_.GetDialogButtons(); |
| 557 // Simply having just an OK button is *not* supported. See comment on function | 621 // Simply having just an OK button is *not* supported. See comment on function |
| 558 // GetDialogButtons in dialog_delegate.h for reasons. | 622 // GetDialogButtons in dialog_delegate.h for reasons. |
| 559 DCHECK_GT(buttons & ui::DIALOG_BUTTON_CANCEL, 0); | 623 DCHECK_GT(buttons & ui::DIALOG_BUTTON_CANCEL, 0); |
| 560 return buttons; | 624 return buttons; |
| 561 } | 625 } |
| 562 | 626 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 int event_flags) { | 665 int event_flags) { |
| 602 GURL store_url(extension_urls::GetWebstoreItemDetailURLPrefix() + | 666 GURL store_url(extension_urls::GetWebstoreItemDetailURLPrefix() + |
| 603 prompt_.extension()->id()); | 667 prompt_.extension()->id()); |
| 604 OpenURLParams params( | 668 OpenURLParams params( |
| 605 store_url, Referrer(), NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_LINK, | 669 store_url, Referrer(), NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_LINK, |
| 606 false); | 670 false); |
| 607 navigator_->OpenURL(params); | 671 navigator_->OpenURL(params); |
| 608 GetWidget()->Close(); | 672 GetWidget()->Close(); |
| 609 } | 673 } |
| 610 | 674 |
| 675 void ExtensionInstallDialogView::Layout() { |
| 676 views::View* contents_view = scroll_view_->contents(); |
| 677 int content_width = width(); |
| 678 int content_height = contents_view->GetHeightForWidth(content_width); |
| 679 if (content_height > height()) { |
| 680 content_width -= scroll_view_->GetScrollBarWidth(); |
| 681 content_height = contents_view->GetHeightForWidth(content_width); |
| 682 } |
| 683 contents_view->SetBounds(0, 0, content_width, content_height); |
| 684 scroll_view_->SetBounds(0, 0, width(), height()); |
| 685 |
| 686 DialogDelegateView::Layout(); |
| 687 } |
| 688 |
| 689 gfx::Size ExtensionInstallDialogView::GetPreferredSize() { |
| 690 return dialog_size_; |
| 691 } |
| 692 |
| 611 // static | 693 // static |
| 612 ExtensionInstallPrompt::ShowDialogCallback | 694 ExtensionInstallPrompt::ShowDialogCallback |
| 613 ExtensionInstallPrompt::GetDefaultShowDialogCallback() { | 695 ExtensionInstallPrompt::GetDefaultShowDialogCallback() { |
| 614 return base::Bind(&ShowExtensionInstallDialogImpl); | 696 return base::Bind(&ShowExtensionInstallDialogImpl); |
| 615 } | 697 } |
| 616 | 698 |
| 617 // IssueAdviceView::DetailsView ------------------------------------------------ | 699 // ExpandableContainerView::DetailsView ---------------------------------------- |
| 618 | 700 |
| 619 IssueAdviceView::DetailsView::DetailsView(int horizontal_space) | 701 ExpandableContainerView::DetailsView::DetailsView(int horizontal_space, |
| 702 bool show_bullets) |
| 620 : layout_(new views::GridLayout(this)), | 703 : layout_(new views::GridLayout(this)), |
| 621 state_(0) { | 704 state_(0), |
| 705 show_bullets_(show_bullets) { |
| 622 SetLayoutManager(layout_); | 706 SetLayoutManager(layout_); |
| 623 views::ColumnSet* column_set = layout_->AddColumnSet(0); | 707 views::ColumnSet* column_set = layout_->AddColumnSet(0); |
| 708 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); |
| 624 column_set->AddColumn(views::GridLayout::LEADING, | 709 column_set->AddColumn(views::GridLayout::LEADING, |
| 625 views::GridLayout::LEADING, | 710 views::GridLayout::LEADING, |
| 626 0, | 711 0, |
| 627 views::GridLayout::FIXED, | 712 views::GridLayout::FIXED, |
| 628 horizontal_space, | 713 horizontal_space, |
| 629 0); | 714 0); |
| 630 } | 715 } |
| 631 | 716 |
| 632 void IssueAdviceView::DetailsView::AddDetail(const string16& detail) { | 717 void ExpandableContainerView::DetailsView::AddDetail(const string16& detail) { |
| 633 layout_->StartRowWithPadding(0, 0, | 718 layout_->StartRowWithPadding(0, 0, |
| 634 0, views::kRelatedControlSmallVerticalSpacing); | 719 0, views::kRelatedControlSmallVerticalSpacing); |
| 635 views::Label* detail_label = | 720 views::Label* detail_label = |
| 636 new views::Label(PrepareForDisplay(detail, true)); | 721 new views::Label(PrepareForDisplay(detail, show_bullets_)); |
| 637 detail_label->SetMultiLine(true); | 722 detail_label->SetMultiLine(true); |
| 638 detail_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 723 detail_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 639 layout_->AddView(detail_label); | 724 layout_->AddView(detail_label); |
| 640 } | 725 } |
| 641 | 726 |
| 642 gfx::Size IssueAdviceView::DetailsView::GetPreferredSize() { | 727 gfx::Size ExpandableContainerView::DetailsView::GetPreferredSize() { |
| 643 gfx::Size size = views::View::GetPreferredSize(); | 728 gfx::Size size = views::View::GetPreferredSize(); |
| 644 return gfx::Size(size.width(), size.height() * state_); | 729 return gfx::Size(size.width(), size.height() * state_); |
| 645 } | 730 } |
| 646 | 731 |
| 647 void IssueAdviceView::DetailsView::AnimateToState(double state) { | 732 void ExpandableContainerView::DetailsView::AnimateToState(double state) { |
| 648 state_ = state; | 733 state_ = state; |
| 649 PreferredSizeChanged(); | 734 PreferredSizeChanged(); |
| 650 SchedulePaint(); | 735 SchedulePaint(); |
| 651 } | 736 } |
| 652 | 737 |
| 653 // IssueAdviceView ------------------------------------------------------------- | 738 // ExpandableContainerView ----------------------------------------------------- |
| 654 | 739 |
| 655 IssueAdviceView::IssueAdviceView(ExtensionInstallDialogView* owner, | 740 ExpandableContainerView::ExpandableContainerView( |
| 656 const IssueAdviceInfoEntry& issue_advice, | 741 ExtensionInstallDialogView* owner, |
| 657 int horizontal_space) | 742 const string16& description, |
| 743 const PermissionDetails& details, |
| 744 int horizontal_space, |
| 745 bool show_bullets) |
| 658 : owner_(owner), | 746 : owner_(owner), |
| 659 details_view_(NULL), | 747 details_view_(NULL), |
| 660 arrow_view_(NULL), | 748 arrow_view_(NULL), |
| 661 slide_animation_(this) { | 749 slide_animation_(this), |
| 662 // TODO(estade): replace this with a more appropriate image. | 750 expanded_(false) { |
| 663 const gfx::ImageSkia& image = *ui::ResourceBundle::GetSharedInstance(). | |
| 664 GetImageSkiaNamed(IDR_OMNIBOX_TTS); | |
| 665 | |
| 666 views::GridLayout* layout = new views::GridLayout(this); | 751 views::GridLayout* layout = new views::GridLayout(this); |
| 667 SetLayoutManager(layout); | 752 SetLayoutManager(layout); |
| 668 int column_set_id = 0; | 753 int column_set_id = 0; |
| 669 views::ColumnSet* column_set = layout->AddColumnSet(column_set_id); | 754 views::ColumnSet* column_set = layout->AddColumnSet(column_set_id); |
| 670 if (!issue_advice.details.empty()) { | |
| 671 column_set->AddColumn(views::GridLayout::LEADING, | |
| 672 views::GridLayout::LEADING, | |
| 673 0, | |
| 674 views::GridLayout::FIXED, | |
| 675 image.width(), | |
| 676 0); | |
| 677 horizontal_space -= image.width(); | |
| 678 details_view_ = new DetailsView(horizontal_space); | |
| 679 } | |
| 680 column_set->AddColumn(views::GridLayout::LEADING, | 755 column_set->AddColumn(views::GridLayout::LEADING, |
| 681 views::GridLayout::FILL, | 756 views::GridLayout::LEADING, |
| 682 0, | 757 0, |
| 683 views::GridLayout::FIXED, | 758 views::GridLayout::USE_PREF, |
| 684 horizontal_space, | 759 0, |
| 685 0); | 760 0); |
| 686 layout->StartRow(0, column_set_id); | 761 if (!description.empty()) { |
| 762 layout->StartRow(0, column_set_id); |
| 687 | 763 |
| 688 if (details_view_) { | 764 views::Label* description_label = |
| 689 arrow_view_ = new views::ImageView(); | 765 new views::Label(PrepareForDisplay(description, true)); |
| 690 arrow_view_->SetImage(image); | 766 description_label->SetMultiLine(true); |
| 691 arrow_view_->SetVerticalAlignment(views::ImageView::CENTER); | 767 description_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 692 layout->AddView(arrow_view_); | 768 description_label->SizeToFit(horizontal_space); |
| 769 layout->AddView(description_label); |
| 693 } | 770 } |
| 694 | 771 |
| 695 views::Label* description_label = | 772 if (details.empty()) |
| 696 new views::Label(PrepareForDisplay(issue_advice.description, | |
| 697 !details_view_)); | |
| 698 description_label->SetMultiLine(true); | |
| 699 description_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
| 700 description_label->SizeToFit(horizontal_space); | |
| 701 layout->AddView(description_label); | |
| 702 | |
| 703 if (!details_view_) | |
| 704 return; | 773 return; |
| 705 | 774 |
| 775 details_view_ = new DetailsView(horizontal_space, show_bullets); |
| 776 |
| 706 layout->StartRow(0, column_set_id); | 777 layout->StartRow(0, column_set_id); |
| 707 layout->SkipColumns(1); | |
| 708 layout->AddView(details_view_); | 778 layout->AddView(details_view_); |
| 709 | 779 |
| 710 for (size_t i = 0; i < issue_advice.details.size(); ++i) | 780 for (size_t i = 0; i < details.size(); ++i) |
| 711 details_view_->AddDetail(issue_advice.details[i]); | 781 details_view_->AddDetail(details[i]); |
| 782 |
| 783 // Prepare the columns for the More Details row. |
| 784 column_set = layout->AddColumnSet(++column_set_id); |
| 785 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); |
| 786 column_set->AddColumn(views::GridLayout::LEADING, |
| 787 views::GridLayout::LEADING, |
| 788 0, |
| 789 views::GridLayout::USE_PREF, |
| 790 0, |
| 791 0); |
| 792 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); |
| 793 column_set->AddColumn(views::GridLayout::LEADING, |
| 794 views::GridLayout::LEADING, |
| 795 0, |
| 796 views::GridLayout::USE_PREF, |
| 797 0, |
| 798 0); |
| 799 column_set->AddColumn(views::GridLayout::LEADING, |
| 800 views::GridLayout::LEADING, |
| 801 0, |
| 802 views::GridLayout::USE_PREF, |
| 803 0, |
| 804 0); |
| 805 |
| 806 // Add the More Details link. |
| 807 layout->StartRow(0, column_set_id); |
| 808 more_details_ = new views::Link( |
| 809 l10n_util::GetStringUTF16(IDS_EXTENSIONS_SHOW_DETAILS)); |
| 810 more_details_->set_listener(this); |
| 811 more_details_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 812 layout->AddView(more_details_); |
| 813 |
| 814 // Add the arrow after the More Details link. |
| 815 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 816 arrow_toggle_ = new views::ImageButton(this); |
| 817 arrow_toggle_->SetImage(views::Button::STATE_NORMAL, |
| 818 rb.GetImageSkiaNamed(IDR_DOWN_ARROW)); |
| 819 layout->AddView(arrow_toggle_); |
| 712 } | 820 } |
| 713 | 821 |
| 714 bool IssueAdviceView::OnMousePressed(const ui::MouseEvent& event) { | 822 ExpandableContainerView::~ExpandableContainerView() { |
| 715 return details_view_ && event.IsLeftMouseButton(); | |
| 716 } | 823 } |
| 717 | 824 |
| 718 void IssueAdviceView::OnMouseReleased(const ui::MouseEvent& event) { | 825 void ExpandableContainerView::ButtonPressed( |
| 826 views::Button* sender, const ui::Event& event) { |
| 827 ToggleDetailLevel(); |
| 828 } |
| 829 |
| 830 void ExpandableContainerView::LinkClicked( |
| 831 views::Link* source, int event_flags) { |
| 832 ToggleDetailLevel(); |
| 833 } |
| 834 |
| 835 void ExpandableContainerView::AnimationProgressed( |
| 836 const ui::Animation* animation) { |
| 837 DCHECK_EQ(&slide_animation_, animation); |
| 838 if (details_view_) |
| 839 details_view_->AnimateToState(animation->GetCurrentValue()); |
| 840 } |
| 841 |
| 842 void ExpandableContainerView::AnimationEnded(const ui::Animation* animation) { |
| 843 if (animation->GetCurrentValue() != 0.0) { |
| 844 arrow_toggle_->SetImage( |
| 845 views::Button::STATE_NORMAL, |
| 846 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
| 847 IDR_UP_ARROW)); |
| 848 } else { |
| 849 arrow_toggle_->SetImage( |
| 850 views::Button::STATE_NORMAL, |
| 851 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
| 852 IDR_DOWN_ARROW)); |
| 853 } |
| 854 |
| 855 more_details_->SetText(expanded_ ? |
| 856 l10n_util::GetStringUTF16(IDS_EXTENSIONS_HIDE_DETAILS) : |
| 857 l10n_util::GetStringUTF16(IDS_EXTENSIONS_SHOW_DETAILS)); |
| 858 } |
| 859 |
| 860 void ExpandableContainerView::ChildPreferredSizeChanged(views::View* child) { |
| 861 owner_->ContentsChanged(); |
| 862 } |
| 863 |
| 864 void ExpandableContainerView::ToggleDetailLevel() { |
| 865 expanded_ = !expanded_; |
| 866 |
| 719 if (slide_animation_.IsShowing()) | 867 if (slide_animation_.IsShowing()) |
| 720 slide_animation_.Hide(); | 868 slide_animation_.Hide(); |
| 721 else | 869 else |
| 722 slide_animation_.Show(); | 870 slide_animation_.Show(); |
| 723 } | 871 } |
| 724 | |
| 725 void IssueAdviceView::AnimationProgressed(const ui::Animation* animation) { | |
| 726 DCHECK_EQ(animation, &slide_animation_); | |
| 727 | |
| 728 if (details_view_) | |
| 729 details_view_->AnimateToState(animation->GetCurrentValue()); | |
| 730 | |
| 731 if (arrow_view_) { | |
| 732 gfx::Transform rotate; | |
| 733 if (animation->GetCurrentValue() != 0.0) { | |
| 734 rotate.Translate(arrow_view_->width() / 2.0, | |
| 735 arrow_view_->height() / 2.0); | |
| 736 // TODO(estade): for some reason there are rendering errors at 90 degrees. | |
| 737 // Figure out why. | |
| 738 rotate.Rotate(animation->GetCurrentValue() * 89); | |
| 739 rotate.Translate(-arrow_view_->width() / 2.0, | |
| 740 -arrow_view_->height() / 2.0); | |
| 741 } | |
| 742 arrow_view_->SetTransform(rotate); | |
| 743 } | |
| 744 } | |
| 745 | |
| 746 void IssueAdviceView::ChildPreferredSizeChanged(views::View* child) { | |
| 747 owner_->SizeToContents(); | |
| 748 } | |
| OLD | NEW |