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