1 // Copyright 2014 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_scan_result_dialog_views.h"
7 #include "chrome/browser/ui/views/extensions/media_gallery_checkbox_view.h"
8 #include "components/web_modal/web_contents_modal_dialog_host.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 "grit/generated_resources.h"
13 #include "grit/locale_settings.h"
14 #include "ui/base/l10n/l10n_util.h"
15 #include "ui/views/border.h"
16 #include "ui/views/controls/button/checkbox.h"
17 #include "ui/views/controls/button/image_button.h"
18 #include "ui/views/controls/label.h"
19 #include "ui/views/controls/menu/menu_runner.h"
20 #include "ui/views/controls/scroll_view.h"
21 #include "ui/views/layout/box_layout.h"
22 #include "ui/views/layout/grid_layout.h"
23 #include "ui/views/layout/layout_constants.h"
24 #include "ui/views/view.h"
25 #include "ui/views/widget/widget.h"
26 #include "ui/views/window/dialog_client_view.h"
28 typedef MediaGalleriesScanResultDialogController::OrderedScanResults
33 const int kScrollAreaHeight
= 192;
35 // This container has the right Layout() impl to use within a ScrollView.
36 class ScrollableView
: public views::View
{
39 virtual ~ScrollableView() {}
41 virtual void Layout() OVERRIDE
;
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();
52 width
= parent()->width();
53 height
= std::max(parent()->height(), height
);
55 SetBounds(x(), y(), width
, height
);
57 views::View::Layout();
62 MediaGalleriesScanResultDialogViews::MediaGalleriesScanResultDialogViews(
63 MediaGalleriesScanResultDialogController
* controller
)
64 : controller_(controller
),
66 contents_(new views::View()),
70 // Ownership of |contents_| is handed off by this call. |window_| will take
71 // care of deleting itself after calling DeleteDelegate().
72 web_modal::WebContentsModalDialogManager
* web_contents_modal_dialog_manager
=
73 web_modal::WebContentsModalDialogManager::FromWebContents(
74 controller
->web_contents());
75 DCHECK(web_contents_modal_dialog_manager
);
76 web_modal::WebContentsModalDialogManagerDelegate
* modal_delegate
=
77 web_contents_modal_dialog_manager
->delegate();
78 DCHECK(modal_delegate
);
79 window_
= views::Widget::CreateWindowAsFramelessChild(
80 this, modal_delegate
->GetWebContentsModalDialogHost()->GetHostView());
81 web_contents_modal_dialog_manager
->ShowModalDialog(
82 window_
->GetNativeView());
85 MediaGalleriesScanResultDialogViews::~MediaGalleriesScanResultDialogViews() {}
87 void MediaGalleriesScanResultDialogViews::InitChildViews() {
88 // Outer dialog layout.
89 contents_
->RemoveAllChildViews(true);
90 int dialog_content_width
= views::Widget::GetLocalizedContentsWidth(
91 IDS_MEDIA_GALLERIES_DIALOG_CONTENT_WIDTH_CHARS
);
92 views::GridLayout
* layout
= views::GridLayout::CreatePanel(contents_
);
93 contents_
->SetLayoutManager(layout
);
95 int column_set_id
= 0;
96 views::ColumnSet
* columns
= layout
->AddColumnSet(column_set_id
);
97 columns
->AddColumn(views::GridLayout::LEADING
,
98 views::GridLayout::LEADING
,
100 views::GridLayout::FIXED
,
101 dialog_content_width
,
105 views::Label
* subtext
= new views::Label(controller_
->GetSubtext());
106 subtext
->SetMultiLine(true);
107 subtext
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
108 layout
->StartRow(0, column_set_id
);
111 views::GridLayout::FILL
, views::GridLayout::LEADING
,
112 dialog_content_width
, subtext
->GetHeightForWidth(dialog_content_width
));
113 layout
->AddPaddingRow(0, views::kRelatedControlVerticalSpacing
);
115 // Scrollable area for checkboxes.
116 ScrollableView
* scroll_container
= new ScrollableView();
117 scroll_container
->SetLayoutManager(new views::BoxLayout(
118 views::BoxLayout::kVertical
, 0, 0,
119 views::kRelatedControlSmallVerticalSpacing
));
120 scroll_container
->SetBorder(views::Border::CreateEmptyBorder(
121 views::kRelatedControlVerticalSpacing
,
123 views::kRelatedControlVerticalSpacing
,
126 // Add galleries checkboxes.
127 gallery_view_map_
.clear();
128 OrderedScanResults scan_results
= controller_
->GetGalleryList();
129 for (OrderedScanResults::const_iterator it
= scan_results
.begin();
130 it
!= scan_results
.end();
133 if (it
+ 1 == scan_results
.end())
134 spacing
= views::kRelatedControlSmallVerticalSpacing
;
135 AddOrUpdateScanResult(it
->pref_info
, it
->selected
, scroll_container
,
139 // Add the scrollable area to the outer dialog view. It will squeeze against
140 // the title/subtitle and buttons to occupy all available space in the dialog.
141 views::ScrollView
* scroll_view
=
142 views::ScrollView::CreateScrollViewWithBorder();
143 scroll_view
->SetContents(scroll_container
);
144 layout
->StartRowWithPadding(1, column_set_id
,
145 0, views::kRelatedControlVerticalSpacing
);
146 layout
->AddView(scroll_view
, 1, 1,
147 views::GridLayout::FILL
, views::GridLayout::FILL
,
148 dialog_content_width
, kScrollAreaHeight
);
151 void MediaGalleriesScanResultDialogViews::UpdateResults() {
156 bool MediaGalleriesScanResultDialogViews::AddOrUpdateScanResult(
157 const MediaGalleryPrefInfo
& gallery
,
159 views::View
* container
,
160 int trailing_vertical_space
) {
161 base::string16 label
= gallery
.GetGalleryDisplayName();
162 base::string16 tooltip_text
= gallery
.GetGalleryTooltip();
163 base::string16 details
= gallery
.GetGalleryAdditionalDetails();
164 bool is_attached
= gallery
.IsGalleryAvailable();
166 GalleryViewMap::iterator it
= gallery_view_map_
.find(gallery
.pref_id
);
167 if (it
!= gallery_view_map_
.end()) {
168 views::Checkbox
* checkbox
= it
->second
->checkbox();
169 checkbox
->SetChecked(selected
);
170 checkbox
->SetText(label
);
171 checkbox
->SetTooltipText(tooltip_text
);
172 it
->second
->folder_viewer_button()->SetVisible(is_attached
);
173 it
->second
->secondary_text()->SetText(details
);
174 it
->second
->secondary_text()->SetVisible(details
.length() > 0);
178 MediaGalleryCheckboxView
* gallery_view
=
179 new MediaGalleryCheckboxView(label
, tooltip_text
, details
, is_attached
,
180 trailing_vertical_space
, this, this);
181 gallery_view
->checkbox()->SetChecked(selected
);
182 container
->AddChildView(gallery_view
);
184 gallery_view_map_
[gallery
.pref_id
] = gallery_view
;
189 base::string16
MediaGalleriesScanResultDialogViews::GetWindowTitle() const {
190 return controller_
->GetHeader();
193 void MediaGalleriesScanResultDialogViews::DeleteDelegate() {
194 controller_
->DialogFinished(accepted_
);
197 views::Widget
* MediaGalleriesScanResultDialogViews::GetWidget() {
198 return contents_
->GetWidget();
201 const views::Widget
* MediaGalleriesScanResultDialogViews::GetWidget() const {
202 return contents_
->GetWidget();
205 views::View
* MediaGalleriesScanResultDialogViews::GetContentsView() {
209 base::string16
MediaGalleriesScanResultDialogViews::GetDialogButtonLabel(
210 ui::DialogButton button
) const {
211 return l10n_util::GetStringUTF16(button
== ui::DIALOG_BUTTON_OK
?
212 IDS_MEDIA_GALLERIES_SCAN_RESULT_DIALOG_CONFIRM
:
213 IDS_MEDIA_GALLERIES_DIALOG_CANCEL
);
216 ui::ModalType
MediaGalleriesScanResultDialogViews::GetModalType() const {
218 return ui::MODAL_TYPE_CHILD
;
220 return views::WidgetDelegate::GetModalType();
224 bool MediaGalleriesScanResultDialogViews::Cancel() {
228 bool MediaGalleriesScanResultDialogViews::Accept() {
234 void MediaGalleriesScanResultDialogViews::ButtonPressed(
235 views::Button
* sender
,
236 const ui::Event
& event
) {
237 GetWidget()->client_view()->AsDialogClientView()->UpdateDialogButtons();
239 for (GalleryViewMap::const_iterator it
= gallery_view_map_
.begin();
240 it
!= gallery_view_map_
.end(); ++it
) {
241 if (sender
== it
->second
->checkbox()) {
242 controller_
->DidToggleGalleryId(it
->first
,
243 it
->second
->checkbox()->checked());
246 if (sender
== it
->second
->folder_viewer_button()) {
247 controller_
->DidClickOpenFolderViewer(it
->first
);
253 void MediaGalleriesScanResultDialogViews::ShowContextMenuForView(
255 const gfx::Point
& point
,
256 ui::MenuSourceType source_type
) {
257 for (GalleryViewMap::const_iterator it
= gallery_view_map_
.begin();
258 it
!= gallery_view_map_
.end(); ++it
) {
259 if (it
->second
->Contains(source
)) {
260 ShowContextMenu(point
, source_type
, it
->first
);
267 void MediaGalleriesScanResultDialogViews::ShowContextMenu(
268 const gfx::Point
& point
,
269 ui::MenuSourceType source_type
,
270 MediaGalleryPrefId id
) {
271 context_menu_runner_
.reset(new views::MenuRunner(
272 controller_
->GetContextMenu(id
)));
274 if (context_menu_runner_
->RunMenuAt(
277 gfx::Rect(point
.x(), point
.y(), 0, 0),
278 views::MENU_ANCHOR_TOPLEFT
,
280 views::MenuRunner::HAS_MNEMONICS
| views::MenuRunner::CONTEXT_MENU
) ==
281 views::MenuRunner::MENU_DELETED
) {
286 void MediaGalleriesScanResultDialogViews::AcceptDialogForTesting() {
289 web_modal::WebContentsModalDialogManager
* web_contents_modal_dialog_manager
=
290 web_modal::WebContentsModalDialogManager::FromWebContents(
291 controller_
->web_contents());
292 DCHECK(web_contents_modal_dialog_manager
);
293 web_modal::WebContentsModalDialogManager::TestApi(
294 web_contents_modal_dialog_manager
).CloseAllDialogs();
297 // MediaGalleriesScanResultDialogViewsController -------------------------------
300 MediaGalleriesScanResultDialog
* MediaGalleriesScanResultDialog::Create(
301 MediaGalleriesScanResultDialogController
* controller
) {
302 return new MediaGalleriesScanResultDialogViews(controller
);