Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(239)

Side by Side Diff: chrome/browser/cocoa/preferences_window_controller.mm

Issue 340045: [Mac] Prefs layout work for "basics" and "personal stuff"... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/cocoa/preferences_window_controller.h ('k') | chrome/chrome.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "chrome/browser/cocoa/preferences_window_controller.h" 5 #import "chrome/browser/cocoa/preferences_window_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include "app/l10n_util.h" 8 #include "app/l10n_util.h"
9 #include "base/mac_util.h" 9 #include "base/mac_util.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
(...skipping 19 matching lines...) Expand all
30 #include "chrome/common/notification_observer.h" 30 #include "chrome/common/notification_observer.h"
31 #include "chrome/common/notification_type.h" 31 #include "chrome/common/notification_type.h"
32 #include "chrome/common/pref_names.h" 32 #include "chrome/common/pref_names.h"
33 #include "chrome/common/pref_service.h" 33 #include "chrome/common/pref_service.h"
34 #include "chrome/common/url_constants.h" 34 #include "chrome/common/url_constants.h"
35 #include "chrome/installer/util/google_update_settings.h" 35 #include "chrome/installer/util/google_update_settings.h"
36 #include "grit/chromium_strings.h" 36 #include "grit/chromium_strings.h"
37 #include "grit/generated_resources.h" 37 #include "grit/generated_resources.h"
38 #include "grit/locale_settings.h" 38 #include "grit/locale_settings.h"
39 #include "net/base/cookie_policy.h" 39 #include "net/base/cookie_policy.h"
40 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
40 41
41 NSString* const kUserDoneEditingPrefsNotification = 42 NSString* const kUserDoneEditingPrefsNotification =
42 @"kUserDoneEditingPrefsNotification"; 43 @"kUserDoneEditingPrefsNotification";
43 44
44 namespace { 45 namespace {
45 46
46 std::wstring GetNewTabUIURLString() { 47 std::wstring GetNewTabUIURLString() {
47 std::wstring temp = UTF8ToWide(chrome::kChromeUINewTabURL); 48 std::wstring temp = UTF8ToWide(chrome::kChromeUINewTabURL);
48 return URLFixerUpper::FixupURL(temp, std::wstring()); 49 return URLFixerUpper::FixupURL(temp, std::wstring());
49 } 50 }
50 51
51 // Adjusts the views origin so it will be centered if in a given width parent. 52 // Adjusts the views origin so it will be centered if in a given width parent.
52 void CenterViewForWidth(NSView* view, CGFloat width) { 53 void CenterViewForWidth(NSView* view, CGFloat width) {
53 NSRect frame = [view frame]; 54 NSRect frame = [view frame];
54 frame.origin.x = (width - NSWidth(frame)) / 2.0; 55 frame.origin.x = (width - NSWidth(frame)) / 2.0;
55 [view setFrame:frame]; 56 [view setFrame:frame];
56 } 57 }
57 58
58 // Helper to remove all but the last view from the view heirarchy. 59 // Helper to remove all but the last view from the view heirarchy.
59 void RemoveAllButLastView(NSArray* views) { 60 void RemoveAllButLastView(NSArray* views) {
60 NSArray* toRemove = [views subarrayWithRange:NSMakeRange(0, [views count]-1)]; 61 NSArray* toRemove = [views subarrayWithRange:NSMakeRange(0, [views count]-1)];
61 for (NSView* view in toRemove) { 62 for (NSView* view in toRemove) {
62 [view removeFromSuperviewWithoutNeedingDisplay]; 63 [view removeFromSuperviewWithoutNeedingDisplay];
63 } 64 }
64 } 65 }
65 66
67 // Helper for tweaking the prefs window, if view is a:
68 // checkbox, radio group or label: it gets a forced wrap at current size
69 // editable field: left as is
70 // anything else: do +[GTMUILocalizerAndLayoutTweaker sizeToFitView:]
71 NSSize WrapOrSizeToFit(NSView* view) {
72 if ([view isKindOfClass:[NSTextField class]]) {
73 NSTextField* textField = static_cast<NSTextField*>(view);
74 if ([textField isEditable])
75 return NSZeroSize;
76 CGFloat heightChange =
77 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:textField];
78 return NSMakeSize(0.0, heightChange);
79 }
80 if ([view isKindOfClass:[NSMatrix class]]) {
81 NSMatrix* radioGroup = static_cast<NSMatrix*>(view);
82 [GTMUILocalizerAndLayoutTweaker wrapRadioGroupForWidth:radioGroup];
83 return [GTMUILocalizerAndLayoutTweaker sizeToFitView:view];
84 }
85 if ([view isKindOfClass:[NSButton class]]) {
86 NSButton* button = static_cast<NSButton*>(view);
87 NSButtonCell* buttonCell = [button cell];
88 // Decide it's a checkbox via showsStateBy and highlightsBy.
89 if (([buttonCell showsStateBy] == NSCellState) &&
90 ([buttonCell highlightsBy] == NSCellState)) {
91 [GTMUILocalizerAndLayoutTweaker wrapButtonTitleForWidth:button];
92 return [GTMUILocalizerAndLayoutTweaker sizeToFitView:view];
93 }
94 }
95 return [GTMUILocalizerAndLayoutTweaker sizeToFitView:view];
96 }
97
98 // The different behaviors for the "pref group" auto sizing.
99 enum AutoSizeGroupBehavior {
100 kAutoSizeGroupBehaviorVerticalToFit,
101 kAutoSizeGroupBehaviorVerticalFirstToFit,
102 kAutoSizeGroupBehaviorHorizontalToFit,
103 kAutoSizeGroupBehaviorHorizontalFirstGrows
104 };
105
106 // Helper to tweak the layout of the "pref groups" and also ripple any height
107 // changes from one group to the next groups' origins.
108 // |views| is an ordered list of views with first being the label for the
109 // group and the rest being top down or left to right ordering of the views.
110 // The label is assumed to already be the same height as all the views it is
111 // next too.
112 CGFloat AutoSizeGroup(NSArray* views, AutoSizeGroupBehavior behavior,
113 CGFloat verticalShift) {
114 DCHECK_GE([views count], 2U) << "Should be at least a label and a control";
115 NSTextField* label = [views objectAtIndex:0];
116
117 #ifndef NDEBUG
118 // Validate the helpers assumptions in debug builds.
119 DCHECK([label isKindOfClass:[NSTextField class]])
120 << "First view should be the label for the group";
121 NSRect initialLabelRect = [label frame];
122 for (NSView* view in views) {
123 if (view != label) {
124 DCHECK_GE(NSMaxY(initialLabelRect), NSMaxY([view frame]))
125 << "Got a view that goes above the group label";
126 DCHECK_LE(NSMinY(initialLabelRect), NSMinY([view frame]))
127 << "Got a view that goes below the group label";
128 }
129 }
130 #endif // DEBUG
Mark Mentovai 2009/10/30 22:19:27 NDEBUG
131
132 // Auto size the label to see if we need more vertical space for its localized
133 // string.
134 CGFloat labelHeightChange =
135 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:label];
136
137 CGFloat localVerticalShift = 0.0;
138 switch (behavior) {
139 case kAutoSizeGroupBehaviorVerticalToFit: {
140 // Walk bottom up doing the sizing and moves.
141 for (NSUInteger idx = [views count] - 1; idx > 0; --idx) {
142 NSView* view = [views objectAtIndex:idx];
143 NSSize delta = WrapOrSizeToFit(view);
144 DCHECK_GE(delta.height, 0.0) << "Should NOT shrink in height";
145 if (localVerticalShift) {
146 NSPoint origin = [view frame].origin;
147 origin.y += localVerticalShift;
148 [view setFrameOrigin:origin];
149 }
150 localVerticalShift += delta.height;
151 }
152 break;
153 }
154 case kAutoSizeGroupBehaviorVerticalFirstToFit: {
155 // Just size the top one.
156 NSView* view = [views objectAtIndex:1];
157 NSSize delta = WrapOrSizeToFit(view);
158 DCHECK_GE(delta.height, 0.0) << "Should NOT shrink in height";
159 localVerticalShift += delta.height;
160 break;
161 }
162 case kAutoSizeGroupBehaviorHorizontalToFit: {
163 // Walk left to right doing the sizing and moves.
164 // NOTE: Don't worry about vertical, assume it always fits.
165 CGFloat horizontalShift = 0.0;
166 for (NSUInteger idx = 1; idx < [views count]; ++idx) {
167 NSView* view = [views objectAtIndex:idx];
168 NSSize delta = WrapOrSizeToFit(view);
169 DCHECK_GE(delta.height, 0.0) << "Should NOT shrink in height";
170 if (horizontalShift) {
171 NSPoint origin = [view frame].origin;
172 origin.x += horizontalShift;
173 [view setFrameOrigin:origin];
174 }
175 horizontalShift += delta.width;
176 }
177 break;
178 }
179 case kAutoSizeGroupBehaviorHorizontalFirstGrows: {
180 // Walk right to left doing the sizing and moves, then apply the space
181 // collected into the first.
182 // NOTE: Don't worry about vertical, assume it always all fits.
183 CGFloat horizontalShift = 0.0;
184 for (NSUInteger idx = [views count] - 1; idx > 1; --idx) {
185 NSView* view = [views objectAtIndex:idx];
186 NSSize delta = WrapOrSizeToFit(view);
187 DCHECK_GE(delta.height, 0.0) << "Should NOT shrink in height";
188 horizontalShift -= delta.width;
189 NSPoint origin = [view frame].origin;
190 origin.x += horizontalShift;
191 [view setFrameOrigin:origin];
192 }
193 if (horizontalShift) {
194 NSView* view = [views objectAtIndex:1];
195 NSSize delta = NSMakeSize(horizontalShift, 0.0);
196 [GTMUILocalizerAndLayoutTweaker
197 resizeViewWithoutAutoResizingSubViews:view
198 delta:delta];
199 }
200 break;
201 }
202 default:
203 NOTREACHED();
204 break;
205 }
206
207 // If the label grew more then the views, the other views get an extra shift.
208 // Otherwise, move the label to its top is aligned with the other views.
209 CGFloat nonLabelShift = 0.0;
210 if (labelHeightChange > localVerticalShift) {
211 // Since the lable is taller, centering the other views looks best, just
212 // shift the views by 1/2 of the size difference.
213 nonLabelShift = (labelHeightChange - localVerticalShift) / 2.0;
214 } else {
215 NSPoint origin = [label frame].origin;
216 origin.y += localVerticalShift - labelHeightChange;
217 [label setFrameOrigin:origin];
218 }
219
220 // Apply the input shift requested along with any the shift from label being
221 // taller then the rest of the group.
222 for (NSView* view in views) {
223 NSPoint origin = [view frame].origin;
224 origin.y += verticalShift;
225 if (view != label) {
226 origin.y += nonLabelShift;
227 }
228 [view setFrameOrigin:origin];
229 }
230
231 // Return how much the group grew.
232 return localVerticalShift + nonLabelShift;
233 }
234
66 } // namespace 235 } // namespace
67 236
68 //------------------------------------------------------------------------- 237 //-------------------------------------------------------------------------
69 238
70 @interface PreferencesWindowController(Private) 239 @interface PreferencesWindowController(Private)
71 // Callback when preferences are changed. |prefName| is the name of the 240 // Callback when preferences are changed. |prefName| is the name of the
72 // pref that has changed. 241 // pref that has changed.
73 - (void)prefChanged:(std::wstring*)prefName; 242 - (void)prefChanged:(std::wstring*)prefName;
74 // Record the user performed a certain action and save the preferences. 243 // Record the user performed a certain action and save the preferences.
75 - (void)recordUserAction:(const wchar_t*)action; 244 - (void)recordUserAction:(const wchar_t*)action;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 [animation_ setDelegate:self]; 340 [animation_ setDelegate:self];
172 // The default duration is 0.5s, which actually feels slow in here, so speed 341 // The default duration is 0.5s, which actually feels slow in here, so speed
173 // it up a bit. 342 // it up a bit.
174 [animation_ setDuration:0.2]; 343 [animation_ setDuration:0.2];
175 [animation_ setAnimationBlockingMode:NSAnimationNonblocking]; 344 [animation_ setAnimationBlockingMode:NSAnimationNonblocking];
176 } 345 }
177 return self; 346 return self;
178 } 347 }
179 348
180 - (void)awakeFromNib { 349 - (void)awakeFromNib {
181 NSRect underTheHoodFrame = [underTheHoodView_ frame]; 350
351 // Do runtime fixup of the "basics" and "personal stuff" pages for the
352 // strings. Work bottom up shifting views up as needed, and then resize the
353 // page.
354 CGFloat verticalShift = 0.0;
355 verticalShift += AutoSizeGroup(basicsGroupDefaultBrowser_,
356 kAutoSizeGroupBehaviorVerticalFirstToFit,
357 verticalShift);
358 verticalShift += AutoSizeGroup(basicsGroupSearchEngine_,
359 kAutoSizeGroupBehaviorHorizontalFirstGrows,
360 verticalShift);
361 verticalShift += AutoSizeGroup(basicsGroupToolbar_,
362 kAutoSizeGroupBehaviorVerticalToFit,
363 verticalShift);
364 verticalShift += AutoSizeGroup(basicsGroupHomePage_,
365 kAutoSizeGroupBehaviorVerticalToFit,
366 verticalShift);
367 verticalShift += AutoSizeGroup(basicsGroupStartup_,
368 kAutoSizeGroupBehaviorVerticalFirstToFit,
369 verticalShift);
370 [GTMUILocalizerAndLayoutTweaker
371 resizeViewWithoutAutoResizingSubViews:basicsView_
372 delta:NSMakeSize(0.0, verticalShift)];
373 verticalShift = 0.0;
Mark Mentovai 2009/10/30 22:19:27 nit: blank line before doing the second pane.
374 verticalShift += AutoSizeGroup(personalStuffGroupThemes_,
375 kAutoSizeGroupBehaviorHorizontalToFit,
376 verticalShift);
377 verticalShift += AutoSizeGroup(personalStuffGroupBrowserData_,
378 kAutoSizeGroupBehaviorVerticalToFit,
379 verticalShift);
380 verticalShift += AutoSizeGroup(personalStuffGroupAutofill_,
381 kAutoSizeGroupBehaviorVerticalToFit,
382 verticalShift);
383 verticalShift += AutoSizeGroup(personalStuffGroupPasswords_,
384 kAutoSizeGroupBehaviorVerticalFirstToFit,
385 verticalShift);
386 [GTMUILocalizerAndLayoutTweaker
387 resizeViewWithoutAutoResizingSubViews:personalStuffView_
388 delta:NSMakeSize(0.0, verticalShift)];
182 389
183 // Make sure the window is wide enough to fit the the widest view 390 // Make sure the window is wide enough to fit the the widest view
391 NSRect underTheHoodFrame = [underTheHoodView_ frame];
184 CGFloat widest = std::max(NSWidth([basicsView_ frame]), 392 CGFloat widest = std::max(NSWidth([basicsView_ frame]),
185 NSWidth([personalStuffView_ frame])); 393 NSWidth([personalStuffView_ frame]));
186 widest = std::max(widest, NSWidth(underTheHoodFrame)); 394 widest = std::max(widest, NSWidth(underTheHoodFrame));
187 NSWindow* prefsWindow = [self window]; 395 NSWindow* prefsWindow = [self window];
188 NSRect frame = [prefsWindow frame]; 396 NSRect frame = [prefsWindow frame];
189 frame.size.width = widest; 397 frame.size.width = widest;
190 [prefsWindow setFrame:frame display:NO]; 398 [prefsWindow setFrame:frame display:NO];
191 399
192 // The Under the Hood prefs is a scroller, it shouldn't get any border, so it 400 // The Under the Hood prefs is a scroller, it shouldn't get any border, so it
193 // gets resized to the as wide as the window ends up. 401 // gets resized to the as wide as the window ends up.
194 underTheHoodFrame.size.width = widest; 402 underTheHoodFrame.size.width = widest;
195 [underTheHoodView_ setFrame:underTheHoodFrame]; 403 [underTheHoodView_ setFrame:underTheHoodFrame];
196 // Widen the Under the Hood content so things can rewrap 404 // Widen the Under the Hood content so things can rewrap
197 NSSize advancedContentSize = [advancedView_ frame].size; 405 NSSize advancedContentSize = [advancedView_ frame].size;
198 advancedContentSize.width = [advancedScroller_ contentSize].width; 406 advancedContentSize.width = [advancedScroller_ contentSize].width;
199 [advancedView_ setFrameSize:advancedContentSize]; 407 [advancedView_ setFrameSize:advancedContentSize];
200 408
201 // Put the advanced view into the scroller and scroll it to the top.
202 [advancedScroller_ setDocumentView:advancedView_];
203 [advancedView_ scrollPoint:NSMakePoint(0, advancedContentSize.height)];
204
205 // Adjust the view origins so they show up centered. 409 // Adjust the view origins so they show up centered.
206 CenterViewForWidth(basicsView_, widest); 410 CenterViewForWidth(basicsView_, widest);
207 CenterViewForWidth(personalStuffView_, widest); 411 CenterViewForWidth(personalStuffView_, widest);
208 CenterViewForWidth(underTheHoodView_, widest); 412 CenterViewForWidth(underTheHoodView_, widest);
209 413
210 // Ensure the "basics" is selected. 414 // Put the advanced view into the scroller and scroll it to the top.
415 [advancedScroller_ setDocumentView:advancedView_];
416 [advancedView_ scrollPoint:NSMakePoint(0, advancedContentSize.height)];
417
418 // Ensure the "basics" page is selected.
211 // TODO: change this to remember what's selected in a preference and restore 419 // TODO: change this to remember what's selected in a preference and restore
212 // it. 420 // it.
213
214 NSToolbarItem* firstItem = [[toolbar_ items] objectAtIndex:0]; 421 NSToolbarItem* firstItem = [[toolbar_ items] objectAtIndex:0];
215 [self displayPreferenceViewForToolbarItem:firstItem animate:NO]; 422 [self displayPreferenceViewForToolbarItem:firstItem animate:NO];
216 [toolbar_ setSelectedItemIdentifier:[firstItem itemIdentifier]]; 423 [toolbar_ setSelectedItemIdentifier:[firstItem itemIdentifier]];
217 424
218 // TODO(pinkerton): save/restore position based on prefs. 425 // TODO(pinkerton): save/restore position based on prefs.
219 [[self window] center]; 426 [[self window] center];
220 } 427 }
221 428
222 - (void)dealloc { 429 - (void)dealloc {
223 [customPagesSource_ removeObserver:self forKeyPath:@"customHomePages"]; 430 [customPagesSource_ removeObserver:self forKeyPath:@"customHomePages"];
(...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 [[NSNotificationCenter defaultCenter] 1349 [[NSNotificationCenter defaultCenter]
1143 postNotificationName:kUserDoneEditingPrefsNotification 1350 postNotificationName:kUserDoneEditingPrefsNotification
1144 object:self]; 1351 object:self];
1145 } 1352 }
1146 1353
1147 - (void)controlTextDidEndEditing:(NSNotification*)notification { 1354 - (void)controlTextDidEndEditing:(NSNotification*)notification {
1148 [customPagesSource_ validateURLs]; 1355 [customPagesSource_ validateURLs];
1149 } 1356 }
1150 1357
1151 @end 1358 @end
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/preferences_window_controller.h ('k') | chrome/chrome.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698