media_galleries_dialog_views.cc revision 5e3f23d412006dc4db4e659864679f29341e113f
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->StartRow(0, column_set_id); 131 layout->AddView(subtext); 132 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 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 int spacing = 0; 151 if (iter + 1 == permissions.end()) 152 spacing = views::kRelatedControlSmallVerticalSpacing; 153 AddOrUpdateGallery(iter->pref_info, iter->allowed, scroll_container, 154 spacing); 155 } 156 157 // Separator line. 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, 0); 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 0, 206 views::kRelatedControlVerticalSpacing, 207 0)); 208 add_gallery_container->AddChildView(add_gallery_button_); 209 210 layout->StartRowWithPadding(0, column_set_id, 211 0, views::kRelatedControlVerticalSpacing); 212 layout->AddView(add_gallery_container); 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 int trailing_vertical_space) { 232 string16 label = 233 MediaGalleriesDialogController::GetGalleryDisplayNameNoAttachment( 234 gallery); 235 string16 tooltip_text = 236 MediaGalleriesDialogController::GetGalleryTooltip(gallery); 237 string16 details = 238 MediaGalleriesDialogController::GetGalleryAdditionalDetails(gallery); 239 240 CheckboxMap::iterator iter = checkbox_map_.find(gallery.pref_id); 241 if (iter != checkbox_map_.end()) { 242 views::Checkbox* checkbox = iter->second; 243 checkbox->SetChecked(permitted); 244 checkbox->SetText(label); 245 checkbox->SetTooltipText(tooltip_text); 246 // Replace the details string. 247 views::View* checkbox_view = checkbox->parent(); 248 DCHECK_EQ(2, checkbox_view->child_count()); 249 views::Label* secondary_text = 250 static_cast<views::Label*>(checkbox_view->child_at(1)); 251 secondary_text->SetText(details); 252 253 // Why is this returning false? Looks like that will mean it doesn't paint. 254 return false; 255 } 256 257 views::Checkbox* checkbox = new views::Checkbox(label); 258 checkbox->set_listener(this); 259 checkbox->SetTooltipText(tooltip_text); 260 views::Label* secondary_text = new views::Label(details); 261 secondary_text->SetTooltipText(tooltip_text); 262 secondary_text->SetEnabledColor(kDeemphasizedTextColor); 263 secondary_text->SetTooltipText(tooltip_text); 264 secondary_text->set_border(views::Border::CreateEmptyBorder( 265 0, 266 views::kRelatedControlSmallHorizontalSpacing, 267 0, 268 views::kRelatedControlSmallHorizontalSpacing)); 269 270 views::View* checkbox_view = new views::View(); 271 checkbox_view->set_border(views::Border::CreateEmptyBorder( 272 0, 273 views::kPanelHorizMargin, 274 trailing_vertical_space, 275 0)); 276 checkbox_view->SetLayoutManager( 277 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0)); 278 checkbox_view->AddChildView(checkbox); 279 checkbox_view->AddChildView(secondary_text); 280 281 container->AddChildView(checkbox_view); 282 283 checkbox->SetChecked(permitted); 284 checkbox_map_[gallery.pref_id] = checkbox; 285 286 return true; 287} 288 289string16 MediaGalleriesDialogViews::GetWindowTitle() const { 290 return controller_->GetHeader(); 291} 292 293bool MediaGalleriesDialogViews::ShouldShowWindowTitle() const { 294 return DialogDelegate::UseNewStyle(); 295} 296 297void MediaGalleriesDialogViews::DeleteDelegate() { 298 controller_->DialogFinished(accepted_); 299} 300 301views::Widget* MediaGalleriesDialogViews::GetWidget() { 302 return contents_->GetWidget(); 303} 304 305const views::Widget* MediaGalleriesDialogViews::GetWidget() const { 306 return contents_->GetWidget(); 307} 308 309views::View* MediaGalleriesDialogViews::GetContentsView() { 310 return contents_; 311} 312 313string16 MediaGalleriesDialogViews::GetDialogButtonLabel( 314 ui::DialogButton button) const { 315 return l10n_util::GetStringUTF16(button == ui::DIALOG_BUTTON_OK ? 316 IDS_MEDIA_GALLERIES_DIALOG_CONFIRM : 317 IDS_MEDIA_GALLERIES_DIALOG_CANCEL); 318} 319 320bool MediaGalleriesDialogViews::IsDialogButtonEnabled( 321 ui::DialogButton button) const { 322 return button != ui::DIALOG_BUTTON_OK || confirm_available_; 323} 324 325ui::ModalType MediaGalleriesDialogViews::GetModalType() const { 326#if defined(USE_ASH) 327 return ui::MODAL_TYPE_CHILD; 328#else 329 return views::WidgetDelegate::GetModalType(); 330#endif 331} 332 333bool MediaGalleriesDialogViews::Cancel() { 334 return true; 335} 336 337bool MediaGalleriesDialogViews::Accept() { 338 accepted_ = true; 339 340 return true; 341} 342 343// TODO(wittman): Remove this override once we move to the new style frame view 344// on all dialogs. 345views::NonClientFrameView* MediaGalleriesDialogViews::CreateNonClientFrameView( 346 views::Widget* widget) { 347 return CreateConstrainedStyleNonClientFrameView( 348 widget, 349 controller_->web_contents()->GetBrowserContext()); 350} 351 352void MediaGalleriesDialogViews::ButtonPressed(views::Button* sender, 353 const ui::Event& event) { 354 confirm_available_ = true; 355 GetWidget()->client_view()->AsDialogClientView()->UpdateDialogButtons(); 356 357 if (sender == add_gallery_button_) { 358 controller_->OnAddFolderClicked(); 359 return; 360 } 361 362 for (CheckboxMap::const_iterator iter = checkbox_map_.begin(); 363 iter != checkbox_map_.end(); ++iter) { 364 if (sender == iter->second) { 365 controller_->DidToggleGalleryId(iter->first, 366 iter->second->checked()); 367 return; 368 } 369 } 370} 371 372// MediaGalleriesDialogViewsController ----------------------------------------- 373 374// static 375MediaGalleriesDialog* MediaGalleriesDialog::Create( 376 MediaGalleriesDialogController* controller) { 377 return new MediaGalleriesDialogViews(controller); 378} 379 380} // namespace chrome 381