| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2013 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 #import "ui/message_center/cocoa/settings_controller.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 | |
| 9 #include "base/mac/foundation_util.h" | |
| 10 #import "base/mac/scoped_nsobject.h" | |
| 11 #include "base/stl_util.h" | |
| 12 #include "base/strings/sys_string_conversions.h" | |
| 13 #include "skia/ext/skia_utils_mac.h" | |
| 14 #include "ui/base/l10n/l10n_util.h" | |
| 15 #import "ui/message_center/cocoa/opaque_views.h" | |
| 16 #import "ui/message_center/cocoa/settings_entry_view.h" | |
| 17 #import "ui/message_center/cocoa/tray_view_controller.h" | |
| 18 #include "ui/message_center/message_center_style.h" | |
| 19 #include "ui/strings/grit/ui_strings.h" | |
| 20 | |
| 21 using message_center::settings::kHorizontalMargin; | |
| 22 using message_center::settings::kEntryHeight; | |
| 23 | |
| 24 // Intrinsic padding pixels out of our control. | |
| 25 const int kIntrinsicHeaderTextTopPadding = 3; | |
| 26 const int kIntrinsicSubheaderTextTopPadding = 5; | |
| 27 const int kIntrinsicSubheaderTextBottomPadding = 3; | |
| 28 const int kIntrinsicDropDownVerticalPadding = 2; | |
| 29 const int kIntrinsicDropDownHorizontalPadding = 3; | |
| 30 | |
| 31 // Corrected padding values used in layout. | |
| 32 // Calculated additional blank space above the header text, including | |
| 33 // the intrinsic blank space above the header label. | |
| 34 const int kCorrectedHeaderTextTopPadding = | |
| 35 message_center::settings::kTopMargin - kIntrinsicHeaderTextTopPadding; | |
| 36 | |
| 37 // Calculated additional blank space above the subheader text, including | |
| 38 // the intrinsic blank space above the subheader label. | |
| 39 const int kCorrectedSubheaderTextTopPadding = | |
| 40 message_center::settings::kTitleToDescriptionSpace - | |
| 41 kIntrinsicSubheaderTextTopPadding; | |
| 42 | |
| 43 // Calcoulated additional vertical padding for the drop-down, including the | |
| 44 // blank space included with the drop-down control. | |
| 45 const int kCorrectedDropDownTopPadding = | |
| 46 message_center::settings::kDescriptionToSwitcherSpace - | |
| 47 kIntrinsicDropDownVerticalPadding - kIntrinsicSubheaderTextBottomPadding; | |
| 48 | |
| 49 // Calculated additional horizontal blank space for the drop down, including | |
| 50 // the blank space included with the drop-down control. | |
| 51 const int kCorrectedDropDownMargin = | |
| 52 kHorizontalMargin - kIntrinsicDropDownHorizontalPadding; | |
| 53 | |
| 54 @interface MCSettingsController (Private) | |
| 55 // Sets the icon on the checkbox corresponding to |notifiers_[index]|. | |
| 56 - (void)setIcon:(NSImage*)icon forNotifierIndex:(size_t)index; | |
| 57 | |
| 58 - (void)setIcon:(NSImage*)icon | |
| 59 forNotifierId:(const message_center::NotifierId&)id; | |
| 60 | |
| 61 // Returns the NSButton corresponding to the checkbox for |notifiers_[index]|. | |
| 62 - (MCSettingsEntryView*)entryForNotifierAtIndex:(size_t)index; | |
| 63 | |
| 64 // Update the contents view. | |
| 65 - (void)updateView; | |
| 66 | |
| 67 // Handler for the notifier group dropdown menu. | |
| 68 - (void)notifierGroupSelectionChanged:(id)sender; | |
| 69 | |
| 70 @end | |
| 71 | |
| 72 namespace message_center { | |
| 73 | |
| 74 NotifierSettingsObserverMac::~NotifierSettingsObserverMac() {} | |
| 75 | |
| 76 void NotifierSettingsObserverMac::UpdateIconImage(const NotifierId& notifier_id, | |
| 77 const gfx::Image& icon) { | |
| 78 [settings_controller_ setIcon:icon.AsNSImage() forNotifierId:notifier_id]; | |
| 79 } | |
| 80 | |
| 81 void NotifierSettingsObserverMac::NotifierGroupChanged() { | |
| 82 [settings_controller_ updateView]; | |
| 83 } | |
| 84 | |
| 85 void NotifierSettingsObserverMac::NotifierEnabledChanged( | |
| 86 const NotifierId& notifier_id, bool enabled) {} | |
| 87 | |
| 88 } // namespace message_center | |
| 89 | |
| 90 @implementation MCSettingsController | |
| 91 | |
| 92 - (id)initWithProvider:(message_center::NotifierSettingsProvider*)provider | |
| 93 trayViewController:(MCTrayViewController*)trayViewController { | |
| 94 if ((self = [super initWithNibName:nil bundle:nil])) { | |
| 95 observer_.reset(new message_center::NotifierSettingsObserverMac(self)); | |
| 96 provider_ = provider; | |
| 97 trayViewController_ = trayViewController; | |
| 98 provider_->AddObserver(observer_.get()); | |
| 99 } | |
| 100 return self; | |
| 101 } | |
| 102 | |
| 103 - (void)dealloc { | |
| 104 provider_->RemoveObserver(observer_.get()); | |
| 105 provider_->OnNotifierSettingsClosing(); | |
| 106 STLDeleteElements(¬ifiers_); | |
| 107 [super dealloc]; | |
| 108 } | |
| 109 | |
| 110 - (NSTextField*)newLabelWithFrame:(NSRect)frame { | |
| 111 NSColor* color = gfx::SkColorToCalibratedNSColor( | |
| 112 message_center::kMessageCenterBackgroundColor); | |
| 113 MCTextField* label = | |
| 114 [[MCTextField alloc] initWithFrame:frame backgroundColor:color]; | |
| 115 | |
| 116 return label; | |
| 117 } | |
| 118 | |
| 119 - (void)updateView { | |
| 120 notifiers_.clear(); | |
| 121 [trayViewController_ updateSettings]; | |
| 122 } | |
| 123 | |
| 124 - (void)loadView { | |
| 125 DCHECK(notifiers_.empty()); | |
| 126 provider_->GetNotifierList(¬ifiers_); | |
| 127 CGFloat maxHeight = [MCTrayViewController maxTrayClientHeight]; | |
| 128 | |
| 129 // Container view. | |
| 130 NSRect fullFrame = | |
| 131 NSMakeRect(0, 0, [MCTrayViewController trayWidth], maxHeight); | |
| 132 base::scoped_nsobject<NSBox> view([[NSBox alloc] initWithFrame:fullFrame]); | |
| 133 [view setBorderType:NSNoBorder]; | |
| 134 [view setBoxType:NSBoxCustom]; | |
| 135 [view setContentViewMargins:NSZeroSize]; | |
| 136 [view setFillColor:gfx::SkColorToCalibratedNSColor( | |
| 137 message_center::kMessageCenterBackgroundColor)]; | |
| 138 [view setTitlePosition:NSNoTitle]; | |
| 139 [self setView:view]; | |
| 140 | |
| 141 // "Settings" text. | |
| 142 NSRect headerFrame = NSMakeRect(kHorizontalMargin, | |
| 143 kHorizontalMargin, | |
| 144 NSWidth(fullFrame), | |
| 145 NSHeight(fullFrame)); | |
| 146 settingsText_.reset([self newLabelWithFrame:headerFrame]); | |
| 147 [settingsText_ setTextColor: | |
| 148 gfx::SkColorToCalibratedNSColor(message_center::kRegularTextColor)]; | |
| 149 [settingsText_ | |
| 150 setFont:[NSFont messageFontOfSize:message_center::kTitleFontSize]]; | |
| 151 | |
| 152 [settingsText_ setStringValue: | |
| 153 l10n_util::GetNSString(IDS_MESSAGE_CENTER_SETTINGS_BUTTON_LABEL)]; | |
| 154 [settingsText_ sizeToFit]; | |
| 155 headerFrame = [settingsText_ frame]; | |
| 156 headerFrame.origin.y = NSMaxY(fullFrame) - kCorrectedHeaderTextTopPadding - | |
| 157 NSHeight(headerFrame); | |
| 158 [[self view] addSubview:settingsText_]; | |
| 159 | |
| 160 // Subheader. | |
| 161 NSRect subheaderFrame = NSMakeRect(kHorizontalMargin, | |
| 162 kHorizontalMargin, | |
| 163 NSWidth(fullFrame), | |
| 164 NSHeight(fullFrame)); | |
| 165 detailsText_.reset([self newLabelWithFrame:subheaderFrame]); | |
| 166 [detailsText_ setTextColor: | |
| 167 gfx::SkColorToCalibratedNSColor(message_center::kDimTextColor)]; | |
| 168 [detailsText_ | |
| 169 setFont:[NSFont messageFontOfSize:message_center::kMessageFontSize]]; | |
| 170 | |
| 171 size_t groupCount = provider_->GetNotifierGroupCount(); | |
| 172 [detailsText_ setStringValue:l10n_util::GetNSString( | |
| 173 groupCount > 1 ? IDS_MESSAGE_CENTER_SETTINGS_DESCRIPTION_MULTIUSER | |
| 174 : IDS_MESSAGE_CENTER_SETTINGS_DIALOG_DESCRIPTION)]; | |
| 175 [detailsText_ sizeToFit]; | |
| 176 subheaderFrame = [detailsText_ frame]; | |
| 177 subheaderFrame.origin.y = | |
| 178 NSMinY(headerFrame) - kCorrectedSubheaderTextTopPadding - | |
| 179 NSHeight(subheaderFrame); | |
| 180 [[self view] addSubview:detailsText_]; | |
| 181 | |
| 182 // Profile switcher is only needed for more than one profile. | |
| 183 NSRect dropDownButtonFrame = subheaderFrame; | |
| 184 if (groupCount > 1) { | |
| 185 dropDownButtonFrame = NSMakeRect(kCorrectedDropDownMargin, | |
| 186 kHorizontalMargin, | |
| 187 NSWidth(fullFrame), | |
| 188 NSHeight(fullFrame)); | |
| 189 groupDropDownButton_.reset( | |
| 190 [[MCDropDown alloc] initWithFrame:dropDownButtonFrame pullsDown:YES]); | |
| 191 [groupDropDownButton_ | |
| 192 setBackgroundColor:gfx::SkColorToCalibratedNSColor( | |
| 193 message_center::kMessageCenterBackgroundColor)]; | |
| 194 [groupDropDownButton_ setAction:@selector(notifierGroupSelectionChanged:)]; | |
| 195 [groupDropDownButton_ setTarget:self]; | |
| 196 // Add a dummy item for pull-down. | |
| 197 [groupDropDownButton_ addItemWithTitle:@""]; | |
| 198 base::string16 title; | |
| 199 for (size_t i = 0; i < groupCount; ++i) { | |
| 200 const message_center::NotifierGroup& group = | |
| 201 provider_->GetNotifierGroupAt(i); | |
| 202 base::string16 item = | |
| 203 group.login_info.empty() ? group.name : group.login_info; | |
| 204 [groupDropDownButton_ addItemWithTitle:base::SysUTF16ToNSString(item)]; | |
| 205 if (provider_->IsNotifierGroupActiveAt(i)) { | |
| 206 title = item; | |
| 207 [[groupDropDownButton_ lastItem] setState:NSOnState]; | |
| 208 } | |
| 209 } | |
| 210 [groupDropDownButton_ setTitle:base::SysUTF16ToNSString(title)]; | |
| 211 [groupDropDownButton_ sizeToFit]; | |
| 212 dropDownButtonFrame = [groupDropDownButton_ frame]; | |
| 213 dropDownButtonFrame.origin.y = | |
| 214 NSMinY(subheaderFrame) - kCorrectedDropDownTopPadding - | |
| 215 NSHeight(dropDownButtonFrame); | |
| 216 dropDownButtonFrame.size.width = | |
| 217 NSWidth(fullFrame) - 2 * kCorrectedDropDownMargin; | |
| 218 [[self view] addSubview:groupDropDownButton_]; | |
| 219 } | |
| 220 | |
| 221 // Document view for the notifier settings. | |
| 222 CGFloat y = 0; | |
| 223 NSRect documentFrame = NSMakeRect(0, 0, NSWidth(fullFrame), 0); | |
| 224 base::scoped_nsobject<NSView> documentView( | |
| 225 [[NSView alloc] initWithFrame:documentFrame]); | |
| 226 int notifierCount = notifiers_.size(); | |
| 227 for (int i = notifierCount - 1; i >= 0; --i) { | |
| 228 message_center::Notifier* notifier = notifiers_[i]; | |
| 229 // TODO(thakis): Use a custom button cell. | |
| 230 NSRect frame = NSMakeRect(kHorizontalMargin, | |
| 231 y, | |
| 232 NSWidth(documentFrame) - kHorizontalMargin * 2, | |
| 233 kEntryHeight); | |
| 234 | |
| 235 base::scoped_nsobject<MCSettingsEntryView> entryView( | |
| 236 [[MCSettingsEntryView alloc] | |
| 237 initWithController:self | |
| 238 notifier:notifier | |
| 239 frame:frame | |
| 240 hasSeparator:(i != notifierCount - 1)]); | |
| 241 [documentView addSubview:entryView]; | |
| 242 y += NSHeight(frame); | |
| 243 } | |
| 244 | |
| 245 documentFrame.size.height = y - kIntrinsicDropDownVerticalPadding; | |
| 246 [documentView setFrame:documentFrame]; | |
| 247 | |
| 248 // Scroll view for the notifier settings. | |
| 249 NSRect scrollFrame = documentFrame; | |
| 250 scrollFrame.origin.y = 0; | |
| 251 CGFloat remainingHeight = NSMinY(dropDownButtonFrame) - NSMinY(scrollFrame); | |
| 252 | |
| 253 if (NSHeight(documentFrame) < remainingHeight) { | |
| 254 // Everything fits without scrolling. | |
| 255 CGFloat delta = remainingHeight - NSHeight(documentFrame); | |
| 256 headerFrame.origin.y -= delta; | |
| 257 subheaderFrame.origin.y -= delta; | |
| 258 dropDownButtonFrame.origin.y -= delta; | |
| 259 fullFrame.size.height -= delta; | |
| 260 } else { | |
| 261 scrollFrame.size.height = remainingHeight; | |
| 262 } | |
| 263 | |
| 264 scrollView_.reset([[NSScrollView alloc] initWithFrame:scrollFrame]); | |
| 265 [scrollView_ setAutohidesScrollers:YES]; | |
| 266 [scrollView_ setAutoresizingMask:NSViewMinYMargin]; | |
| 267 [scrollView_ setDocumentView:documentView]; | |
| 268 [scrollView_ setDrawsBackground:NO]; | |
| 269 [scrollView_ setHasHorizontalScroller:NO]; | |
| 270 [scrollView_ setHasVerticalScroller:YES]; | |
| 271 | |
| 272 // Scroll to top. | |
| 273 NSPoint newScrollOrigin = | |
| 274 NSMakePoint(0.0, | |
| 275 NSMaxY([[scrollView_ documentView] frame]) - | |
| 276 NSHeight([[scrollView_ contentView] bounds])); | |
| 277 [[scrollView_ documentView] scrollPoint:newScrollOrigin]; | |
| 278 | |
| 279 // Set final sizes. | |
| 280 [[self view] setFrame:fullFrame]; | |
| 281 [[self view] addSubview:scrollView_]; | |
| 282 [settingsText_ setFrame:headerFrame]; | |
| 283 [detailsText_ setFrame:subheaderFrame]; | |
| 284 [groupDropDownButton_ setFrame:dropDownButtonFrame]; | |
| 285 } | |
| 286 | |
| 287 - (void)setSettingsNotifier:(message_center::Notifier*)notifier | |
| 288 enabled:(BOOL)enabled { | |
| 289 provider_->SetNotifierEnabled(*notifier, enabled); | |
| 290 } | |
| 291 | |
| 292 - (void)learnMoreClicked:(message_center::Notifier*)notifier { | |
| 293 provider_->OnNotifierAdvancedSettingsRequested(notifier->notifier_id, NULL); | |
| 294 } | |
| 295 | |
| 296 // Testing API ///////////////////////////////////////////////////////////////// | |
| 297 | |
| 298 - (NSPopUpButton*)groupDropDownButton { | |
| 299 return groupDropDownButton_; | |
| 300 } | |
| 301 | |
| 302 - (NSScrollView*)scrollView { | |
| 303 return scrollView_; | |
| 304 } | |
| 305 | |
| 306 // Private API ///////////////////////////////////////////////////////////////// | |
| 307 | |
| 308 - (void)setIcon:(NSImage*)icon forNotifierIndex:(size_t)index { | |
| 309 MCSettingsEntryView* entry = [self entryForNotifierAtIndex:index]; | |
| 310 [entry setNotifierIcon:icon]; | |
| 311 } | |
| 312 | |
| 313 - (void)setIcon:(NSImage*)icon | |
| 314 forNotifierId:(const message_center::NotifierId&)id { | |
| 315 for (size_t i = 0; i < notifiers_.size(); ++i) { | |
| 316 if (notifiers_[i]->notifier_id == id) { | |
| 317 [self setIcon:icon forNotifierIndex:i]; | |
| 318 return; | |
| 319 } | |
| 320 } | |
| 321 } | |
| 322 | |
| 323 - (MCSettingsEntryView*)entryForNotifierAtIndex:(size_t)index { | |
| 324 NSArray* subviews = [[scrollView_ documentView] subviews]; | |
| 325 // The checkboxes are in bottom-top order, the checkbox for notifiers_[0] is | |
| 326 // last. | |
| 327 DCHECK_LT(notifiers_.size() - 1 - index, [subviews count]); | |
| 328 NSView* view = [subviews objectAtIndex:notifiers_.size() - 1 - index]; | |
| 329 return base::mac::ObjCCastStrict<MCSettingsEntryView>(view); | |
| 330 } | |
| 331 | |
| 332 - (void)notifierGroupSelectionChanged:(id)sender { | |
| 333 DCHECK_EQ(groupDropDownButton_.get(), sender); | |
| 334 NSPopUpButton* button = static_cast<NSPopUpButton*>(sender); | |
| 335 // The first item is a dummy item. | |
| 336 provider_->SwitchToNotifierGroup([button indexOfSelectedItem] - 1); | |
| 337 } | |
| 338 | |
| 339 - (BOOL)notifierHasAdvancedSettings:(const message_center::NotifierId&)id { | |
| 340 return provider_->NotifierHasAdvancedSettings(id); | |
| 341 } | |
| 342 | |
| 343 @end | |
| OLD | NEW |