Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / views / extensions / media_galleries_dialog_views.cc
blob638d63cb1e198b82b29f22fafd86eb93105a9609
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.
5 #include "chrome/browser/ui/views/extensions/media_galleries_dialog_views.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/ui/views/extensions/media_gallery_checkbox_view.h"
9 #include "chrome/grit/generated_resources.h"
10 #include "chrome/grit/locale_settings.h"
11 #include "components/constrained_window/constrained_window_views.h"
12 #include "components/web_modal/web_contents_modal_dialog_manager.h"
13 #include "content/public/browser/web_contents.h"
14 #include "ui/base/l10n/l10n_util.h"
15 #include "ui/native_theme/native_theme.h"
16 #include "ui/views/border.h"
17 #include "ui/views/controls/button/checkbox.h"
18 #include "ui/views/controls/button/image_button.h"
19 #include "ui/views/controls/button/label_button.h"
20 #include "ui/views/controls/label.h"
21 #include "ui/views/controls/menu/menu_runner.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"
31 namespace {
33 const int kScrollAreaHeight = 192;
35 // This container has the right Layout() impl to use within a ScrollView.
36 class ScrollableView : public views::View {
37 public:
38 ScrollableView() {}
39 ~ScrollableView() override {}
41 void Layout() override;
43 private:
44 DISALLOW_COPY_AND_ASSIGN(ScrollableView);
47 void ScrollableView::Layout() {
48 gfx::Size pref = GetPreferredSize();
49 int width = pref.width();
50 int height = pref.height();
51 if (parent()) {
52 width = parent()->width();
53 height = std::max(parent()->height(), height);
55 SetBounds(x(), y(), width, height);
57 views::View::Layout();
60 } // namespace
62 MediaGalleriesDialogViews::MediaGalleriesDialogViews(
63 MediaGalleriesDialogController* controller)
64 : controller_(controller),
65 contents_(new views::View()),
66 auxiliary_button_(NULL),
67 confirm_available_(false),
68 accepted_(false) {
69 InitChildViews();
70 if (ControllerHasWebContents()) {
71 constrained_window::ShowWebModalDialogViews(this,
72 controller->WebContents());
76 MediaGalleriesDialogViews::~MediaGalleriesDialogViews() {
77 if (!ControllerHasWebContents())
78 delete contents_;
81 void MediaGalleriesDialogViews::AcceptDialogForTesting() {
82 accepted_ = true;
84 web_modal::WebContentsModalDialogManager* manager =
85 web_modal::WebContentsModalDialogManager::FromWebContents(
86 controller_->WebContents());
87 DCHECK(manager);
88 web_modal::WebContentsModalDialogManager::TestApi(manager).CloseAllDialogs();
91 void MediaGalleriesDialogViews::InitChildViews() {
92 // Outer dialog layout.
93 contents_->RemoveAllChildViews(true);
94 checkbox_map_.clear();
96 int dialog_content_width = views::Widget::GetLocalizedContentsWidth(
97 IDS_MEDIA_GALLERIES_DIALOG_CONTENT_WIDTH_CHARS);
98 views::GridLayout* layout = views::GridLayout::CreatePanel(contents_);
99 contents_->SetLayoutManager(layout);
101 int column_set_id = 0;
102 views::ColumnSet* columns = layout->AddColumnSet(column_set_id);
103 columns->AddColumn(views::GridLayout::LEADING,
104 views::GridLayout::LEADING,
106 views::GridLayout::FIXED,
107 dialog_content_width,
110 // Message text.
111 views::Label* subtext = new views::Label(controller_->GetSubtext());
112 subtext->SetMultiLine(true);
113 subtext->SetHorizontalAlignment(gfx::ALIGN_LEFT);
114 layout->StartRow(0, column_set_id);
115 layout->AddView(
116 subtext, 1, 1,
117 views::GridLayout::FILL, views::GridLayout::LEADING,
118 dialog_content_width, subtext->GetHeightForWidth(dialog_content_width));
119 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
121 // Scrollable area for checkboxes.
122 ScrollableView* scroll_container = new ScrollableView();
123 scroll_container->SetLayoutManager(new views::BoxLayout(
124 views::BoxLayout::kVertical, 0, 0,
125 views::kRelatedControlSmallVerticalSpacing));
126 scroll_container->SetBorder(
127 views::Border::CreateEmptyBorder(views::kRelatedControlVerticalSpacing,
129 views::kRelatedControlVerticalSpacing,
130 0));
132 std::vector<base::string16> section_headers =
133 controller_->GetSectionHeaders();
134 for (size_t i = 0; i < section_headers.size(); i++) {
135 MediaGalleriesDialogController::Entries entries =
136 controller_->GetSectionEntries(i);
138 // Header and separator line.
139 if (!section_headers[i].empty() && !entries.empty()) {
140 views::Separator* separator = new views::Separator(
141 views::Separator::HORIZONTAL);
142 scroll_container->AddChildView(separator);
144 views::Label* header = new views::Label(section_headers[i]);
145 header->SetMultiLine(true);
146 header->SetHorizontalAlignment(gfx::ALIGN_LEFT);
147 header->SetBorder(views::Border::CreateEmptyBorder(
148 views::kRelatedControlVerticalSpacing,
149 views::kPanelHorizMargin,
150 views::kRelatedControlVerticalSpacing,
151 0));
152 scroll_container->AddChildView(header);
155 // Checkboxes.
156 MediaGalleriesDialogController::Entries::const_iterator iter;
157 for (iter = entries.begin(); iter != entries.end(); ++iter) {
158 int spacing = 0;
159 if (iter + 1 == entries.end())
160 spacing = views::kRelatedControlSmallVerticalSpacing;
161 AddOrUpdateGallery(*iter, scroll_container, spacing);
165 confirm_available_ = controller_->IsAcceptAllowed();
167 // Add the scrollable area to the outer dialog view. It will squeeze against
168 // the title/subtitle and buttons to occupy all available space in the dialog.
169 views::ScrollView* scroll_view =
170 views::ScrollView::CreateScrollViewWithBorder();
171 scroll_view->SetContents(scroll_container);
172 layout->StartRowWithPadding(1, column_set_id,
173 0, views::kRelatedControlVerticalSpacing);
174 layout->AddView(scroll_view, 1, 1,
175 views::GridLayout::FILL, views::GridLayout::FILL,
176 dialog_content_width, kScrollAreaHeight);
179 void MediaGalleriesDialogViews::UpdateGalleries() {
180 InitChildViews();
181 contents_->Layout();
183 if (ControllerHasWebContents())
184 GetWidget()->client_view()->AsDialogClientView()->UpdateDialogButtons();
187 bool MediaGalleriesDialogViews::AddOrUpdateGallery(
188 const MediaGalleriesDialogController::Entry& gallery,
189 views::View* container,
190 int trailing_vertical_space) {
191 bool show_folder_viewer = controller_->ShouldShowFolderViewer(gallery);
193 CheckboxMap::iterator iter = checkbox_map_.find(gallery.pref_info.pref_id);
194 if (iter != checkbox_map_.end()) {
195 views::Checkbox* checkbox = iter->second->checkbox();
196 checkbox->SetChecked(gallery.selected);
197 checkbox->SetText(gallery.pref_info.GetGalleryDisplayName());
198 checkbox->SetTooltipText(gallery.pref_info.GetGalleryTooltip());
199 base::string16 details = gallery.pref_info.GetGalleryAdditionalDetails();
200 iter->second->secondary_text()->SetText(details);
201 iter->second->secondary_text()->SetVisible(details.length() > 0);
202 iter->second->folder_viewer_button()->SetVisible(show_folder_viewer);
203 return false;
206 MediaGalleryCheckboxView* gallery_view =
207 new MediaGalleryCheckboxView(gallery.pref_info, show_folder_viewer,
208 trailing_vertical_space, this, this);
209 gallery_view->checkbox()->SetChecked(gallery.selected);
210 container->AddChildView(gallery_view);
211 checkbox_map_[gallery.pref_info.pref_id] = gallery_view;
213 return true;
216 base::string16 MediaGalleriesDialogViews::GetWindowTitle() const {
217 return controller_->GetHeader();
220 void MediaGalleriesDialogViews::DeleteDelegate() {
221 controller_->DialogFinished(accepted_);
224 views::Widget* MediaGalleriesDialogViews::GetWidget() {
225 return contents_->GetWidget();
228 const views::Widget* MediaGalleriesDialogViews::GetWidget() const {
229 return contents_->GetWidget();
232 views::View* MediaGalleriesDialogViews::GetContentsView() {
233 return contents_;
236 base::string16 MediaGalleriesDialogViews::GetDialogButtonLabel(
237 ui::DialogButton button) const {
238 if (button == ui::DIALOG_BUTTON_OK)
239 return controller_->GetAcceptButtonText();
240 return l10n_util::GetStringUTF16(IDS_MEDIA_GALLERIES_DIALOG_CANCEL);
243 bool MediaGalleriesDialogViews::IsDialogButtonEnabled(
244 ui::DialogButton button) const {
245 return button != ui::DIALOG_BUTTON_OK || confirm_available_;
248 ui::ModalType MediaGalleriesDialogViews::GetModalType() const {
249 return ui::MODAL_TYPE_CHILD;
252 views::View* MediaGalleriesDialogViews::CreateExtraView() {
253 DCHECK(!auxiliary_button_);
254 base::string16 button_label = controller_->GetAuxiliaryButtonText();
255 if (!button_label.empty()) {
256 auxiliary_button_ = new views::LabelButton(this, button_label);
257 auxiliary_button_->SetStyle(views::Button::STYLE_BUTTON);
259 return auxiliary_button_;
262 bool MediaGalleriesDialogViews::Cancel() {
263 return true;
266 bool MediaGalleriesDialogViews::Accept() {
267 accepted_ = true;
268 return true;
271 void MediaGalleriesDialogViews::ButtonPressed(views::Button* sender,
272 const ui::Event& /* event */) {
273 confirm_available_ = true;
275 if (ControllerHasWebContents())
276 GetWidget()->client_view()->AsDialogClientView()->UpdateDialogButtons();
278 if (sender == auxiliary_button_) {
279 controller_->DidClickAuxiliaryButton();
280 return;
283 for (CheckboxMap::const_iterator iter = checkbox_map_.begin();
284 iter != checkbox_map_.end(); ++iter) {
285 if (sender == iter->second->checkbox()) {
286 controller_->DidToggleEntry(iter->first,
287 iter->second->checkbox()->checked());
288 return;
290 if (sender == iter->second->folder_viewer_button()) {
291 controller_->DidClickOpenFolderViewer(iter->first);
292 return;
297 void MediaGalleriesDialogViews::ShowContextMenuForView(
298 views::View* source,
299 const gfx::Point& point,
300 ui::MenuSourceType source_type) {
301 for (CheckboxMap::const_iterator iter = checkbox_map_.begin();
302 iter != checkbox_map_.end(); ++iter) {
303 if (iter->second->Contains(source)) {
304 ShowContextMenu(point, source_type, iter->first);
305 return;
310 void MediaGalleriesDialogViews::ShowContextMenu(const gfx::Point& point,
311 ui::MenuSourceType source_type,
312 MediaGalleryPrefId id) {
313 context_menu_runner_.reset(new views::MenuRunner(
314 controller_->GetContextMenu(id),
315 views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU));
317 if (context_menu_runner_->RunMenuAt(GetWidget(),
318 NULL,
319 gfx::Rect(point.x(), point.y(), 0, 0),
320 views::MENU_ANCHOR_TOPLEFT,
321 source_type) ==
322 views::MenuRunner::MENU_DELETED) {
323 return;
327 bool MediaGalleriesDialogViews::ControllerHasWebContents() const {
328 return controller_->WebContents() != NULL;
331 // MediaGalleriesDialogViewsController -----------------------------------------
333 // static
334 MediaGalleriesDialog* MediaGalleriesDialog::Create(
335 MediaGalleriesDialogController* controller) {
336 return new MediaGalleriesDialogViews(controller);