blob: d2976f266942c9687a21e6ebac2d71584f9aa743 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa.h"
#include "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h"
#include "chrome/browser/ui/chrome_style.h"
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_alert.h"
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h"
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_control_utils.h"
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h"
#import "chrome/browser/ui/cocoa/key_equivalent_constants.h"
#include "content/public/browser/web_contents.h"
#include "grit/generated_resources.h"
#import "ui/base/cocoa/flipped_view.h"
#import "ui/base/cocoa/menu_controller.h"
#import "ui/base/models/menu_model.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
// Controller for UI events on items in the media galleries dialog.
@interface MediaGalleriesCocoaController : NSObject {
@private
MediaGalleriesDialogCocoa* dialog_;
}
@property(assign, nonatomic) MediaGalleriesDialogCocoa* dialog;
- (void)onAcceptButton:(id)sender;
- (void)onCancelButton:(id)sender;
- (void)onAddFolderClicked:(id)sender;
@end
@implementation MediaGalleriesCocoaController
@synthesize dialog = dialog_;
- (void)onAcceptButton:(id)sender {
dialog_->OnAcceptClicked();
}
- (void)onCancelButton:(id)sender {
dialog_->OnCancelClicked();
}
- (void)onAddFolderClicked:(id)sender {
DCHECK(dialog_);
dialog_->OnAddFolderClicked();
}
@end
namespace {
const CGFloat kCheckboxMargin = 10;
const CGFloat kCheckboxMaxWidth = 440;
const CGFloat kScrollAreaHeight = 220;
} // namespace
MediaGalleriesDialogCocoa::MediaGalleriesDialogCocoa(
MediaGalleriesDialogController* controller,
MediaGalleriesCocoaController* cocoa_controller)
: controller_(controller),
accepted_(false),
cocoa_controller_([cocoa_controller retain]) {
[cocoa_controller_ setDialog:this];
alert_.reset([[ConstrainedWindowAlert alloc] init]);
[alert_ setMessageText:base::SysUTF16ToNSString(controller_->GetHeader())];
[alert_ setInformativeText:
base::SysUTF16ToNSString(controller_->GetSubtext())];
[alert_ addButtonWithTitle:
l10n_util::GetNSString(IDS_MEDIA_GALLERIES_DIALOG_CONFIRM)
keyEquivalent:kKeyEquivalentReturn
target:cocoa_controller_
action:@selector(onAcceptButton:)];
[alert_ addButtonWithTitle:
l10n_util::GetNSString(IDS_MEDIA_GALLERIES_DIALOG_CANCEL)
keyEquivalent:kKeyEquivalentEscape
target:cocoa_controller_
action:@selector(onCancelButton:)];
[alert_ addButtonWithTitle:
l10n_util::GetNSString(IDS_MEDIA_GALLERIES_DIALOG_ADD_GALLERY)
keyEquivalent:kKeyEquivalentNone
target:cocoa_controller_
action:@selector(onAddFolderClicked:)];
[[alert_ closeButton] setTarget:cocoa_controller_];
[[alert_ closeButton] setAction:@selector(onCancelButton:)];
InitDialogControls();
// May be NULL during tests.
if (controller->web_contents()) {
base::scoped_nsobject<CustomConstrainedWindowSheet> sheet(
[[CustomConstrainedWindowSheet alloc]
initWithCustomWindow:[alert_ window]]);
window_.reset(new ConstrainedWindowMac(
this, controller->web_contents(), sheet));
}
}
MediaGalleriesDialogCocoa::~MediaGalleriesDialogCocoa() {
}
void MediaGalleriesDialogCocoa::InitDialogControls() {
main_container_.reset([[NSBox alloc] init]);
[main_container_ setBoxType:NSBoxCustom];
[main_container_ setBorderType:NSLineBorder];
[main_container_ setBorderWidth:1];
[main_container_ setCornerRadius:0];
[main_container_ setContentViewMargins:NSZeroSize];
[main_container_ setTitlePosition:NSNoTitle];
[main_container_ setBorderColor:[NSColor colorWithCalibratedRed:0.625
green:0.625
blue:0.625
alpha:1.0]];
base::scoped_nsobject<NSScrollView> scroll_view(
[[NSScrollView alloc] initWithFrame:
NSMakeRect(0, 0, kCheckboxMaxWidth, kScrollAreaHeight)]);
[scroll_view setHasVerticalScroller:YES];
[scroll_view setHasHorizontalScroller:NO];
[scroll_view setBorderType:NSNoBorder];
[scroll_view setAutohidesScrollers:YES];
[[main_container_ contentView] addSubview:scroll_view];
// Add gallery permission checkboxes inside the scrolling view.
checkbox_container_.reset([[FlippedView alloc] initWithFrame:NSZeroRect]);
CGFloat y_pos = CreateCheckboxes(0, controller_->AttachedPermissions());
if (!controller_->UnattachedPermissions().empty()) {
y_pos = CreateCheckboxSeparator(y_pos);
y_pos = CreateCheckboxes(y_pos, controller_->UnattachedPermissions());
}
// Give the container a reasonable initial size so that the scroll_view can
// figure out the content size.
[checkbox_container_ setFrameSize:NSMakeSize(kCheckboxMaxWidth, y_pos)];
[scroll_view setDocumentView:checkbox_container_];
[checkbox_container_ setFrameSize:NSMakeSize([scroll_view contentSize].width,
y_pos)];
// Resize to pack the scroll view if possible.
NSRect scroll_frame = [scroll_view frame];
if (NSHeight(scroll_frame) > NSHeight([checkbox_container_ frame])) {
scroll_frame.size.height = NSHeight([checkbox_container_ frame]);
[scroll_view setFrameSize:scroll_frame.size];
}
[main_container_ setFrameFromContentFrame:scroll_frame];
[main_container_ setFrameOrigin:NSZeroPoint];
[alert_ setAccessoryView:main_container_];
// As a safeguard against the user skipping reading over the dialog and just
// confirming, the button will be unavailable for dialogs without any checks
// until the user toggles something.
[[[alert_ buttons] objectAtIndex:0] setEnabled:
controller_->IsAcceptAllowed()];
[alert_ layout];
}
CGFloat MediaGalleriesDialogCocoa::CreateCheckboxes(
CGFloat y_pos,
const MediaGalleriesDialogController::GalleryPermissionsVector&
permissions) {
for (MediaGalleriesDialogController::GalleryPermissionsVector::
const_iterator iter = permissions.begin();
iter != permissions.end(); iter++) {
const MediaGalleriesDialogController::GalleryPermission& permission = *iter;
base::scoped_nsobject<MediaGalleryListEntry> checkbox_entry(
[[MediaGalleryListEntry alloc]
initWithFrame:NSZeroRect
controller:this
prefId:permission.gallery_id
galleryName:permission.pref_info.GetGalleryDisplayName()
subscript:permission.pref_info.GetGalleryAdditionalDetails()
tooltip:permission.pref_info.GetGalleryTooltip()
showFolderViewer:false]);
[checkbox_entry setState:permission.allowed];
[checkbox_entry setFrameOrigin:NSMakePoint(0, y_pos)];
y_pos = NSMaxY([checkbox_entry frame]) + kCheckboxMargin;
[checkbox_container_ addSubview:checkbox_entry];
}
return y_pos;
}
CGFloat MediaGalleriesDialogCocoa::CreateCheckboxSeparator(CGFloat y_pos) {
base::scoped_nsobject<NSBox> separator(
[[NSBox alloc] initWithFrame:NSMakeRect(
0, y_pos + kCheckboxMargin * 0.5, kCheckboxMaxWidth, 1.0)]);
[separator setBoxType:NSBoxSeparator];
[separator setBorderType:NSLineBorder];
[separator setAlphaValue:0.2];
[checkbox_container_ addSubview:separator];
y_pos += kCheckboxMargin * 0.5 + 4;
base::scoped_nsobject<NSTextField> unattached_label(
[[NSTextField alloc] initWithFrame:NSZeroRect]);
[unattached_label setEditable:NO];
[unattached_label setSelectable:NO];
[unattached_label setBezeled:NO];
[unattached_label setAttributedStringValue:
constrained_window::GetAttributedLabelString(
base::SysUTF16ToNSString(
controller_->GetUnattachedLocationsHeader()),
chrome_style::kTextFontStyle,
NSNaturalTextAlignment,
NSLineBreakByClipping
)];
[unattached_label sizeToFit];
NSSize unattached_label_size = [unattached_label frame].size;
[unattached_label setFrame:NSMakeRect(
kCheckboxMargin, y_pos + kCheckboxMargin,
kCheckboxMaxWidth, unattached_label_size.height)];
[checkbox_container_ addSubview:unattached_label];
y_pos = NSMaxY([unattached_label frame]) + kCheckboxMargin;
return y_pos;
}
void MediaGalleriesDialogCocoa::OnAcceptClicked() {
accepted_ = true;
if (window_)
window_->CloseWebContentsModalDialog();
}
void MediaGalleriesDialogCocoa::OnCancelClicked() {
if (window_)
window_->CloseWebContentsModalDialog();
}
void MediaGalleriesDialogCocoa::OnAddFolderClicked() {
controller_->OnAddFolderClicked();
}
void MediaGalleriesDialogCocoa::UpdateGalleries() {
InitDialogControls();
}
void MediaGalleriesDialogCocoa::OnConstrainedWindowClosed(
ConstrainedWindowMac* window) {
controller_->DialogFinished(accepted_);
}
void MediaGalleriesDialogCocoa::OnCheckboxToggled(GalleryDialogId gallery_id,
bool checked) {
controller_->DidToggleGallery(gallery_id, checked);
[[[alert_ buttons] objectAtIndex:0] setEnabled:
controller_->IsAcceptAllowed()];
}
ui::MenuModel* MediaGalleriesDialogCocoa::GetContextMenu(
GalleryDialogId gallery_id) {
return controller_->GetContextMenu(gallery_id);
}
// static
MediaGalleriesDialog* MediaGalleriesDialog::Create(
MediaGalleriesDialogController* controller) {
base::scoped_nsobject<MediaGalleriesCocoaController> cocoa_controller(
[[MediaGalleriesCocoaController alloc] init]);
return new MediaGalleriesDialogCocoa(controller, cocoa_controller);
}