Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / views / extensions / media_galleries_dialog_views.cc
blob7da680199b2913d2d17948e9a336690f63bd352f
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/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 "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/native_theme/native_theme.h"
18 #include "ui/views/border.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/menu/menu_runner.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"
32 using web_modal::WebContentsModalDialogManager;
33 using web_modal::WebContentsModalDialogManagerDelegate;
35 namespace {
37 // Equal to the #969696 color used in spec (note WebUI color is #999).
38 const SkColor kDeemphasizedTextColor = SkColorSetRGB(159, 159, 159);
40 const int kScrollAreaHeight = 192;
42 // This container has the right Layout() impl to use within a ScrollView.
43 class ScrollableView : public views::View {
44 public:
45 ScrollableView() {}
46 virtual ~ScrollableView() {}
48 virtual void Layout() OVERRIDE;
50 private:
51 DISALLOW_COPY_AND_ASSIGN(ScrollableView);
54 void 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);
62 SetBounds(x(), y(), width, height);
64 views::View::Layout();
67 } // namespace
69 typedef MediaGalleriesDialogController::GalleryPermissionsVector
70 GalleryPermissionsVector;
72 MediaGalleriesDialogViews::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();
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 WebContentsModalDialogManagerDelegate* modal_delegate =
89 web_contents_modal_dialog_manager->delegate();
90 DCHECK(modal_delegate);
91 window_ = views::Widget::CreateWindowAsFramelessChild(
92 this, modal_delegate->GetWebContentsModalDialogHost()->GetHostView());
93 web_contents_modal_dialog_manager->ShowDialog(window_->GetNativeView());
96 MediaGalleriesDialogViews::~MediaGalleriesDialogViews() {}
98 void MediaGalleriesDialogViews::InitChildViews() {
99 // Outer dialog layout.
100 contents_->RemoveAllChildViews(true);
101 int dialog_content_width = views::Widget::GetLocalizedContentsWidth(
102 IDS_MEDIA_GALLERIES_DIALOG_CONTENT_WIDTH_CHARS);
103 views::GridLayout* layout = views::GridLayout::CreatePanel(contents_);
104 contents_->SetLayoutManager(layout);
106 int column_set_id = 0;
107 views::ColumnSet* columns = layout->AddColumnSet(column_set_id);
108 columns->AddColumn(views::GridLayout::LEADING,
109 views::GridLayout::LEADING,
111 views::GridLayout::FIXED,
112 dialog_content_width,
115 // Message text.
116 views::Label* subtext = new views::Label(controller_->GetSubtext());
117 subtext->SetMultiLine(true);
118 subtext->SetHorizontalAlignment(gfx::ALIGN_LEFT);
119 layout->StartRow(0, column_set_id);
120 layout->AddView(
121 subtext, 1, 1,
122 views::GridLayout::FILL, views::GridLayout::LEADING,
123 dialog_content_width, subtext->GetHeightForWidth(dialog_content_width));
124 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
126 // Scrollable area for checkboxes.
127 ScrollableView* scroll_container = new ScrollableView();
128 scroll_container->SetLayoutManager(new views::BoxLayout(
129 views::BoxLayout::kVertical, 0, 0,
130 views::kRelatedControlSmallVerticalSpacing));
131 scroll_container->set_border(views::Border::CreateEmptyBorder(
132 views::kRelatedControlVerticalSpacing,
134 views::kRelatedControlVerticalSpacing,
135 0));
137 // Add attached galleries checkboxes.
138 checkbox_map_.clear();
139 new_checkbox_map_.clear();
140 GalleryPermissionsVector permissions = controller_->AttachedPermissions();
141 for (GalleryPermissionsVector::const_iterator iter = permissions.begin();
142 iter != permissions.end(); ++iter) {
143 int spacing = 0;
144 if (iter + 1 == permissions.end())
145 spacing = views::kRelatedControlSmallVerticalSpacing;
146 AddOrUpdateGallery(iter->pref_info, iter->allowed, scroll_container,
147 spacing);
150 GalleryPermissionsVector unattached_permissions =
151 controller_->UnattachedPermissions();
153 if (!unattached_permissions.empty()) {
154 // Separator line.
155 views::Separator* separator = new views::Separator(
156 views::Separator::HORIZONTAL);
157 scroll_container->AddChildView(separator);
159 // Unattached locations section.
160 views::Label* unattached_text = new views::Label(
161 controller_->GetUnattachedLocationsHeader());
162 unattached_text->SetMultiLine(true);
163 unattached_text->SetHorizontalAlignment(gfx::ALIGN_LEFT);
164 unattached_text->set_border(views::Border::CreateEmptyBorder(
165 views::kRelatedControlVerticalSpacing,
166 views::kPanelHorizMargin,
167 views::kRelatedControlVerticalSpacing,
168 0));
169 scroll_container->AddChildView(unattached_text);
171 // Add unattached galleries checkboxes.
172 for (GalleryPermissionsVector::const_iterator iter =
173 unattached_permissions.begin();
174 iter != unattached_permissions.end(); ++iter) {
175 AddOrUpdateGallery(iter->pref_info, iter->allowed, scroll_container, 0);
179 confirm_available_ = controller_->HasPermittedGalleries();
181 // Add the scrollable area to the outer dialog view. It will squeeze against
182 // the title/subtitle and buttons to occupy all available space in the dialog.
183 views::ScrollView* scroll_view =
184 views::ScrollView::CreateScrollViewWithBorder();
185 scroll_view->SetContents(scroll_container);
186 layout->StartRowWithPadding(1, column_set_id,
187 0, views::kRelatedControlVerticalSpacing);
188 layout->AddView(scroll_view, 1, 1,
189 views::GridLayout::FILL, views::GridLayout::FILL,
190 dialog_content_width, kScrollAreaHeight);
193 void MediaGalleriesDialogViews::UpdateGalleries() {
194 InitChildViews();
195 contents_->Layout();
198 bool MediaGalleriesDialogViews::AddOrUpdateGallery(
199 const MediaGalleryPrefInfo& gallery,
200 bool permitted,
201 views::View* container,
202 int trailing_vertical_space) {
203 base::string16 label = gallery.GetGalleryDisplayName();
204 base::string16 tooltip_text = gallery.GetGalleryTooltip();
205 base::string16 details = gallery.GetGalleryAdditionalDetails();
207 CheckboxMap::iterator iter = checkbox_map_.find(gallery.pref_id);
208 if (iter != checkbox_map_.end() &&
209 gallery.pref_id != kInvalidMediaGalleryPrefId) {
210 views::Checkbox* checkbox = iter->second;
211 checkbox->SetChecked(permitted);
212 checkbox->SetText(label);
213 checkbox->SetElideBehavior(views::Label::ELIDE_IN_MIDDLE);
214 checkbox->SetTooltipText(tooltip_text);
215 // Replace the details string.
216 views::View* checkbox_view = checkbox->parent();
217 DCHECK_EQ(2, checkbox_view->child_count());
218 views::Label* secondary_text =
219 static_cast<views::Label*>(checkbox_view->child_at(1));
220 secondary_text->SetText(details);
221 return false;
224 views::Checkbox* checkbox = new views::Checkbox(label);
225 checkbox->set_listener(this);
226 if (gallery.pref_id != kInvalidMediaGalleryPrefId)
227 checkbox->set_context_menu_controller(this);
228 checkbox->SetTooltipText(tooltip_text);
229 views::Label* secondary_text = new views::Label(details);
230 if (gallery.pref_id != kInvalidMediaGalleryPrefId)
231 secondary_text->set_context_menu_controller(this);
232 secondary_text->SetTooltipText(tooltip_text);
233 secondary_text->SetEnabledColor(kDeemphasizedTextColor);
234 secondary_text->SetTooltipText(tooltip_text);
235 secondary_text->set_border(views::Border::CreateEmptyBorder(
237 views::kRelatedControlSmallHorizontalSpacing,
239 views::kRelatedControlSmallHorizontalSpacing));
241 views::View* checkbox_view = new views::View();
242 if (gallery.pref_id != kInvalidMediaGalleryPrefId)
243 checkbox_view->set_context_menu_controller(this);
244 checkbox_view->set_border(views::Border::CreateEmptyBorder(
246 views::kPanelHorizMargin,
247 trailing_vertical_space,
248 0));
249 checkbox_view->SetLayoutManager(
250 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0));
251 checkbox_view->AddChildView(checkbox);
252 checkbox_view->AddChildView(secondary_text);
254 container->AddChildView(checkbox_view);
256 checkbox->SetChecked(permitted);
257 if (gallery.pref_id != kInvalidMediaGalleryPrefId)
258 checkbox_map_[gallery.pref_id] = checkbox;
259 else
260 new_checkbox_map_[checkbox] = gallery;
262 return true;
265 base::string16 MediaGalleriesDialogViews::GetWindowTitle() const {
266 return controller_->GetHeader();
269 void MediaGalleriesDialogViews::DeleteDelegate() {
270 controller_->DialogFinished(accepted_);
273 views::Widget* MediaGalleriesDialogViews::GetWidget() {
274 return contents_->GetWidget();
277 const views::Widget* MediaGalleriesDialogViews::GetWidget() const {
278 return contents_->GetWidget();
281 views::View* MediaGalleriesDialogViews::GetContentsView() {
282 return contents_;
285 base::string16 MediaGalleriesDialogViews::GetDialogButtonLabel(
286 ui::DialogButton button) const {
287 return l10n_util::GetStringUTF16(button == ui::DIALOG_BUTTON_OK ?
288 IDS_MEDIA_GALLERIES_DIALOG_CONFIRM :
289 IDS_MEDIA_GALLERIES_DIALOG_CANCEL);
292 bool MediaGalleriesDialogViews::IsDialogButtonEnabled(
293 ui::DialogButton button) const {
294 return button != ui::DIALOG_BUTTON_OK || confirm_available_;
297 ui::ModalType MediaGalleriesDialogViews::GetModalType() const {
298 #if defined(USE_ASH)
299 return ui::MODAL_TYPE_CHILD;
300 #else
301 return views::WidgetDelegate::GetModalType();
302 #endif
305 views::View* MediaGalleriesDialogViews::CreateExtraView() {
306 DCHECK(!add_gallery_button_);
307 add_gallery_button_ = new views::LabelButton(this,
308 l10n_util::GetStringUTF16(IDS_MEDIA_GALLERIES_DIALOG_ADD_GALLERY));
309 add_gallery_button_->SetStyle(views::Button::STYLE_BUTTON);
310 return add_gallery_button_;
313 bool MediaGalleriesDialogViews::Cancel() {
314 return true;
317 bool MediaGalleriesDialogViews::Accept() {
318 accepted_ = true;
320 return true;
323 // TODO(wittman): Remove this override once we move to the new style frame view
324 // on all dialogs.
325 views::NonClientFrameView* MediaGalleriesDialogViews::CreateNonClientFrameView(
326 views::Widget* widget) {
327 return CreateConstrainedStyleNonClientFrameView(
328 widget,
329 controller_->web_contents()->GetBrowserContext());
332 void MediaGalleriesDialogViews::ButtonPressed(views::Button* sender,
333 const ui::Event& event) {
334 confirm_available_ = true;
335 GetWidget()->client_view()->AsDialogClientView()->UpdateDialogButtons();
337 if (sender == add_gallery_button_) {
338 controller_->OnAddFolderClicked();
339 return;
342 for (CheckboxMap::const_iterator iter = checkbox_map_.begin();
343 iter != checkbox_map_.end(); ++iter) {
344 if (sender == iter->second) {
345 controller_->DidToggleGalleryId(iter->first,
346 iter->second->checked());
347 return;
350 for (NewCheckboxMap::const_iterator iter = new_checkbox_map_.begin();
351 iter != new_checkbox_map_.end(); ++iter) {
352 if (sender == iter->first) {
353 controller_->DidToggleNewGallery(iter->second, iter->first->checked());
358 void MediaGalleriesDialogViews::ShowContextMenuForView(
359 views::View* source,
360 const gfx::Point& point,
361 ui::MenuSourceType source_type) {
362 for (CheckboxMap::const_iterator iter = checkbox_map_.begin();
363 iter != checkbox_map_.end(); ++iter) {
364 if (iter->second->parent()->Contains(source)) {
365 ShowContextMenu(point, source_type, iter->first);
366 return;
371 void MediaGalleriesDialogViews::ShowContextMenu(const gfx::Point& point,
372 ui::MenuSourceType source_type,
373 MediaGalleryPrefId id) {
374 context_menu_runner_.reset(new views::MenuRunner(
375 controller_->GetContextMenuModel(id)));
377 if (context_menu_runner_->RunMenuAt(
378 GetWidget(), NULL, gfx::Rect(point.x(), point.y(), 0, 0),
379 views::MenuItemView::TOPLEFT, source_type,
380 views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU) ==
381 views::MenuRunner::MENU_DELETED) {
382 return;
386 // MediaGalleriesDialogViewsController -----------------------------------------
388 // static
389 MediaGalleriesDialog* MediaGalleriesDialog::Create(
390 MediaGalleriesDialogController* controller) {
391 return new MediaGalleriesDialogViews(controller);