media_galleries_dialog_views.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/views/extensions/media_galleries_dialog_views.h" 6 7#include "base/strings/utf_string_conversions.h" 8#include "chrome/browser/ui/views/constrained_window_views.h" 9#include "components/web_modal/web_contents_modal_dialog_manager.h" 10#include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" 11#include "content/public/browser/web_contents.h" 12#include "content/public/browser/web_contents_view.h" 13#include "grit/generated_resources.h" 14#include "grit/locale_settings.h" 15#include "third_party/skia/include/core/SkColor.h" 16#include "ui/base/l10n/l10n_util.h" 17#include "ui/base/resource/resource_bundle.h" 18#include "ui/native_theme/native_theme.h" 19#include "ui/views/controls/button/checkbox.h" 20#include "ui/views/controls/button/label_button.h" 21#include "ui/views/controls/label.h" 22#include "ui/views/controls/scroll_view.h" 23#include "ui/views/controls/separator.h" 24#include "ui/views/layout/box_layout.h" 25#include "ui/views/layout/grid_layout.h" 26#include "ui/views/layout/layout_constants.h" 27#include "ui/views/view.h" 28#include "ui/views/widget/widget.h" 29#include "ui/views/window/dialog_client_view.h" 30 31using web_modal::WebContentsModalDialogManager; 32 33namespace { 34 35// Equal to the #969696 color used in spec (note WebUI color is #999). 36const SkColor kDeemphasizedTextColor = SkColorSetRGB(159, 159, 159); 37 38const int kScrollAreaHeight = 192; 39 40// This container has the right Layout() impl to use within a ScrollView. 41class ScrollableView : public views::View { 42 public: 43 ScrollableView() {} 44 virtual ~ScrollableView() {} 45 46 virtual void Layout() OVERRIDE; 47 48 private: 49 DISALLOW_COPY_AND_ASSIGN(ScrollableView); 50}; 51 52void ScrollableView::Layout() { 53 gfx::Size pref = GetPreferredSize(); 54 int width = pref.width(); 55 int height = pref.height(); 56 if (parent()) { 57 width = std::max(parent()->width(), width); 58 height = std::max(parent()->height(), height); 59 } 60 SetBounds(x(), y(), width, height); 61 62 views::View::Layout(); 63} 64 65} // namespace 66 67namespace chrome { 68 69typedef MediaGalleriesDialogController::GalleryPermissionsVector 70 GalleryPermissionsVector; 71 72MediaGalleriesDialogViews::MediaGalleriesDialogViews( 73 MediaGalleriesDialogController* controller) 74 : controller_(controller), 75 window_(NULL), 76 contents_(new views::View()), 77 add_gallery_button_(NULL), 78 confirm_available_(false), 79 accepted_(false) { 80 InitChildViews(); 81 82 // Ownership of |contents_| is handed off by this call. |window_| will take 83 // care of deleting itself after calling DeleteDelegate(). 84 WebContentsModalDialogManager* web_contents_modal_dialog_manager = 85 WebContentsModalDialogManager::FromWebContents( 86 controller->web_contents()); 87 DCHECK(web_contents_modal_dialog_manager); 88 DCHECK(web_contents_modal_dialog_manager->delegate()); 89 window_ = CreateWebContentsModalDialogViews( 90 this, 91 controller->web_contents()->GetView()->GetNativeView(), 92 web_contents_modal_dialog_manager->delegate()-> 93 GetWebContentsModalDialogHost()); 94 web_contents_modal_dialog_manager->ShowDialog(window_->GetNativeView()); 95} 96 97MediaGalleriesDialogViews::~MediaGalleriesDialogViews() {} 98 99void MediaGalleriesDialogViews::InitChildViews() { 100 // Outer dialog layout. 101 contents_->RemoveAllChildViews(true); 102 int dialog_content_width = views::Widget::GetLocalizedContentsWidth( 103 IDS_MEDIA_GALLERIES_DIALOG_CONTENT_WIDTH_CHARS); 104 views::GridLayout* layout = views::GridLayout::CreatePanel(contents_); 105 contents_->SetLayoutManager(layout); 106 107 int column_set_id = 0; 108 views::ColumnSet* columns = layout->AddColumnSet(column_set_id); 109 columns->AddColumn(views::GridLayout::LEADING, 110 views::GridLayout::LEADING, 111 1, 112 views::GridLayout::FIXED, 113 dialog_content_width, 114 0); 115 116 if (!DialogDelegate::UseNewStyle()) { 117 // Header text. 118 views::Label* header = new views::Label(controller_->GetHeader()); 119 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 120 header->SetFont(rb.GetFont(ui::ResourceBundle::MediumFont)); 121 header->SetHorizontalAlignment(gfx::ALIGN_LEFT); 122 layout->StartRow(0, column_set_id); 123 layout->AddView(header); 124 } 125 126 // Message text. 127 views::Label* subtext = new views::Label(controller_->GetSubtext()); 128 subtext->SetMultiLine(true); 129 subtext->SetHorizontalAlignment(gfx::ALIGN_LEFT); 130 layout->StartRowWithPadding(0, column_set_id, 131 0, views::kRelatedControlVerticalSpacing); 132 layout->AddView(subtext); 133 134 // Scrollable area for checkboxes. 135 ScrollableView* scroll_container = new ScrollableView(); 136 scroll_container->SetLayoutManager(new views::BoxLayout( 137 views::BoxLayout::kVertical, 0, 0, 138 views::kRelatedControlSmallVerticalSpacing)); 139 scroll_container->set_border(views::Border::CreateEmptyBorder( 140 views::kRelatedControlVerticalSpacing, 141 0, 142 views::kRelatedControlVerticalSpacing, 143 0)); 144 145 // Add attached galleries checkboxes. 146 checkbox_map_.clear(); 147 GalleryPermissionsVector permissions = controller_->AttachedPermissions(); 148 for (GalleryPermissionsVector::const_iterator iter = permissions.begin(); 149 iter != permissions.end(); ++iter) { 150 AddOrUpdateGallery(iter->pref_info, iter->allowed, scroll_container); 151 } 152 153 // Separator line. 154 views::View* strut = new views::View; 155 strut->set_border(views::Border::CreateEmptyBorder( 156 views::kRelatedControlVerticalSpacing, 0, 0, 0)); 157 scroll_container->AddChildView(strut); 158 views::Separator* separator = new views::Separator( 159 views::Separator::HORIZONTAL); 160 scroll_container->AddChildView(separator); 161 162 // Unattached locations section. 163 views::Label* unattached_text = new views::Label( 164 controller_->GetUnattachedLocationsHeader()); 165 unattached_text->SetMultiLine(true); 166 unattached_text->SetHorizontalAlignment(gfx::ALIGN_LEFT); 167 unattached_text->set_border(views::Border::CreateEmptyBorder( 168 views::kRelatedControlVerticalSpacing, 169 views::kPanelHorizMargin, 170 views::kRelatedControlVerticalSpacing, 171 0)); 172 scroll_container->AddChildView(unattached_text); 173 174 // Add unattached galleries checkboxes. 175 GalleryPermissionsVector unattached_permissions = 176 controller_->UnattachedPermissions(); 177 for (GalleryPermissionsVector::const_iterator iter = 178 unattached_permissions.begin(); 179 iter != unattached_permissions.end(); ++iter) { 180 AddOrUpdateGallery(iter->pref_info, iter->allowed, scroll_container); 181 } 182 183 confirm_available_ = controller_->HasPermittedGalleries(); 184 185 // Add the scrollable area to the outer dialog view. It will squeeze against 186 // the title/subtitle and buttons to occupy all available space in the dialog. 187 views::ScrollView* scroll_view = 188 views::ScrollView::CreateScrollViewWithBorder(); 189 scroll_view->SetContents(scroll_container); 190 layout->StartRowWithPadding(1, column_set_id, 191 0, views::kRelatedControlVerticalSpacing); 192 layout->AddView(scroll_view, 1, 1, 193 views::GridLayout::FILL, views::GridLayout::FILL, 194 dialog_content_width, kScrollAreaHeight); 195 196 // Add location button. 197 add_gallery_button_ = new views::LabelButton(this, 198 l10n_util::GetStringUTF16(IDS_MEDIA_GALLERIES_DIALOG_ADD_GALLERY)); 199 add_gallery_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); 200 views::View* add_gallery_container = new views::View(); 201 add_gallery_container->SetLayoutManager( 202 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0)); 203 add_gallery_container->set_border(views::Border::CreateEmptyBorder( 204 views::kRelatedControlVerticalSpacing, 205 views::kPanelHorizMargin, 206 views::kRelatedControlVerticalSpacing, 207 0)); 208 add_gallery_container->AddChildView(add_gallery_button_); 209 layout->StartRowWithPadding(0, column_set_id, 210 0, views::kRelatedControlVerticalSpacing); 211 layout->AddView(add_gallery_container, 1, 1, 212 views::GridLayout::LEADING, views::GridLayout::LEADING); 213} 214 215void MediaGalleriesDialogViews::UpdateGallery( 216 const MediaGalleryPrefInfo& gallery, 217 bool permitted) { 218 InitChildViews(); 219 contents_->Layout(); 220} 221 222void MediaGalleriesDialogViews::ForgetGallery(MediaGalleryPrefId gallery) { 223 InitChildViews(); 224 contents_->Layout(); 225} 226 227bool MediaGalleriesDialogViews::AddOrUpdateGallery( 228 const MediaGalleryPrefInfo& gallery, 229 bool permitted, 230 views::View* container) { 231 string16 label = 232 MediaGalleriesDialogController::GetGalleryDisplayNameNoAttachment( 233 gallery); 234 string16 tooltip_text = 235 MediaGalleriesDialogController::GetGalleryTooltip(gallery); 236 string16 details = 237 MediaGalleriesDialogController::GetGalleryAdditionalDetails(gallery); 238 239 CheckboxMap::iterator iter = checkbox_map_.find(gallery.pref_id); 240 if (iter != checkbox_map_.end()) { 241 views::Checkbox* checkbox = iter->second; 242 checkbox->SetChecked(permitted); 243 checkbox->SetText(label); 244 checkbox->SetTooltipText(tooltip_text); 245 // Replace the details string. 246 views::View* checkbox_view = checkbox->parent(); 247 DCHECK_EQ(2, checkbox_view->child_count()); 248 views::Label* secondary_text = 249 static_cast<views::Label*>(checkbox_view->child_at(1)); 250 secondary_text->SetText(details); 251 252 // Why is this returning false? Looks like that will mean it doesn't paint. 253 return false; 254 } 255 256 views::Checkbox* checkbox = new views::Checkbox(label); 257 checkbox->set_listener(this); 258 checkbox->SetTooltipText(tooltip_text); 259 views::Label* secondary_text = new views::Label(details); 260 secondary_text->SetTooltipText(tooltip_text); 261 secondary_text->SetEnabledColor(kDeemphasizedTextColor); 262 secondary_text->SetTooltipText(tooltip_text); 263 secondary_text->set_border(views::Border::CreateEmptyBorder( 264 0, 265 views::kRelatedControlSmallHorizontalSpacing, 266 0, 267 views::kRelatedControlSmallHorizontalSpacing)); 268 269 views::View* checkbox_view = new views::View(); 270 checkbox_view->set_border(views::Border::CreateEmptyBorder( 271 0, 272 views::kPanelHorizMargin, 273 0, 274 0)); 275 checkbox_view->SetLayoutManager( 276 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0)); 277 checkbox_view->AddChildView(checkbox); 278 checkbox_view->AddChildView(secondary_text); 279 280 container->AddChildView(checkbox_view); 281 282 checkbox->SetChecked(permitted); 283 checkbox_map_[gallery.pref_id] = checkbox; 284 285 return true; 286} 287 288string16 MediaGalleriesDialogViews::GetWindowTitle() const { 289 return controller_->GetHeader(); 290} 291 292bool MediaGalleriesDialogViews::ShouldShowWindowTitle() const { 293 return DialogDelegate::UseNewStyle(); 294} 295 296void MediaGalleriesDialogViews::DeleteDelegate() { 297 controller_->DialogFinished(accepted_); 298} 299 300views::Widget* MediaGalleriesDialogViews::GetWidget() { 301 return contents_->GetWidget(); 302} 303 304const views::Widget* MediaGalleriesDialogViews::GetWidget() const { 305 return contents_->GetWidget(); 306} 307 308views::View* MediaGalleriesDialogViews::GetContentsView() { 309 return contents_; 310} 311 312string16 MediaGalleriesDialogViews::GetDialogButtonLabel( 313 ui::DialogButton button) const { 314 return l10n_util::GetStringUTF16(button == ui::DIALOG_BUTTON_OK ? 315 IDS_MEDIA_GALLERIES_DIALOG_CONFIRM : 316 IDS_MEDIA_GALLERIES_DIALOG_CANCEL); 317} 318 319bool MediaGalleriesDialogViews::IsDialogButtonEnabled( 320 ui::DialogButton button) const { 321 return button != ui::DIALOG_BUTTON_OK || confirm_available_; 322} 323 324ui::ModalType MediaGalleriesDialogViews::GetModalType() const { 325#if defined(USE_ASH) 326 return ui::MODAL_TYPE_CHILD; 327#else 328 return views::WidgetDelegate::GetModalType(); 329#endif 330} 331 332bool MediaGalleriesDialogViews::Cancel() { 333 return true; 334} 335 336bool MediaGalleriesDialogViews::Accept() { 337 accepted_ = true; 338 339 return true; 340} 341 342// TODO(wittman): Remove this override once we move to the new style frame view 343// on all dialogs. 344views::NonClientFrameView* MediaGalleriesDialogViews::CreateNonClientFrameView( 345 views::Widget* widget) { 346 return CreateConstrainedStyleNonClientFrameView( 347 widget, 348 controller_->web_contents()->GetBrowserContext()); 349} 350 351void MediaGalleriesDialogViews::ButtonPressed(views::Button* sender, 352 const ui::Event& event) { 353 confirm_available_ = true; 354 GetWidget()->client_view()->AsDialogClientView()->UpdateDialogButtons(); 355 356 if (sender == add_gallery_button_) { 357 controller_->OnAddFolderClicked(); 358 return; 359 } 360 361 for (CheckboxMap::const_iterator iter = checkbox_map_.begin(); 362 iter != checkbox_map_.end(); ++iter) { 363 if (sender == iter->second) { 364 controller_->DidToggleGalleryId(iter->first, 365 iter->second->checked()); 366 return; 367 } 368 } 369} 370 371// MediaGalleriesDialogViewsController ----------------------------------------- 372 373// static 374MediaGalleriesDialog* MediaGalleriesDialog::Create( 375 MediaGalleriesDialogController* controller) { 376 return new MediaGalleriesDialogViews(controller); 377} 378 379} // namespace chrome 380