OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #import "chrome/browser/ui/cocoa/constrained_window/cw_alert.h" | |
6 | |
7 #import "base/logging.h" | |
8 #import "chrome/browser/ui/cocoa/constrained_window/cw_button.h" | |
9 #import "chrome/browser/ui/cocoa/constrained_window/cw_window.h" | |
10 #import "chrome/browser/ui/cocoa/hover_close_button.h" | |
11 #import "chrome/browser/ui/constrained_window.h" | |
12 #include "skia/ext/skia_utils_mac.h" | |
13 #include "ui/base/cocoa/window_size_constants.h" | |
14 | |
15 namespace { | |
16 | |
17 const CGFloat kWindowMinWidth = 500; | |
18 const CGFloat kButtonGap = 6; | |
19 const CGFloat kButtonMinWidth = 72; | |
20 const CGFloat kCloseButtonSize = 16; | |
21 | |
22 scoped_nsobject<NSTextField> CreateLabel() { | |
23 scoped_nsobject<NSTextField> label( | |
24 [[NSTextField alloc] initWithFrame:NSZeroRect]); | |
25 [label setEditable:NO]; | |
26 [label setSelectable:NO]; | |
27 [label setBezeled:NO]; | |
28 [label setDrawsBackground:NO]; | |
29 return label; | |
30 } | |
31 | |
32 NSSize CalculateDesiredSizeForWidth(NSTextField* text_field, CGFloat width) { | |
33 NSRect rect = NSMakeRect(0, 0, width, 1000); | |
34 return [[text_field cell] cellSizeForBounds:rect]; | |
35 } | |
36 | |
37 NSAttributedString* GetAttributedLabelString( | |
38 NSString* string, | |
39 ui::ResourceBundle::FontStyle font_style) { | |
40 const gfx::Font& font = | |
41 ui::ResourceBundle::GetSharedInstance().GetFont(font_style); | |
42 NSColor* color = | |
43 gfx::SkColorToCalibratedNSColor(ConstrainedWindow::kTextColor); | |
44 NSDictionary* attributes = [NSDictionary dictionaryWithObjectsAndKeys: | |
45 font.GetNativeFont(), NSFontAttributeName, | |
46 color, NSForegroundColorAttributeName, | |
47 nil]; | |
48 return [[[NSAttributedString alloc] initWithString:string | |
49 attributes:attributes] autorelease]; | |
50 } | |
51 | |
52 } // namespace | |
53 | |
54 @interface CWAlert() | |
55 - (void)layoutButtonsWithWindowWidth: (CGFloat)windowWidth; | |
56 - (CGFloat)layoutTextField:(NSTextField*)textField | |
57 yPos:(CGFloat)yPos | |
58 windowWidth:(CGFloat)windowWidth; | |
59 - (CGFloat)layoutAccessoryViewAtYPos:(CGFloat)yPos; | |
60 - (void)layoutCloseButtonWithWindowWidth:(CGFloat)windowWidth; | |
61 @end | |
62 | |
63 @implementation CWAlert | |
64 | |
65 - (NSString*)informativeText { | |
66 return [informativeTextField_ stringValue]; | |
67 } | |
68 | |
69 - (void)setInformativeText:(NSString*)string { | |
70 [informativeTextField_ setAttributedStringValue: | |
71 GetAttributedLabelString(string, ConstrainedWindow::kTextFontStyle)]; | |
72 } | |
73 | |
74 - (NSString*)messageText { | |
75 return [messageTextField_ stringValue]; | |
76 } | |
77 | |
78 - (void)setMessageText:(NSString*)string { | |
79 [messageTextField_ setAttributedStringValue: | |
80 GetAttributedLabelString(string, ConstrainedWindow::kTitleFontStyle)]; | |
81 } | |
82 | |
83 - (NSView*)accessoryView { | |
84 return accessoryView_; | |
85 } | |
86 | |
87 - (void)setAccessoryView:(NSView*)accessoryView { | |
88 [accessoryView_ removeFromSuperview]; | |
89 accessoryView_.reset([accessoryView retain]); | |
90 [[window_ contentView] addSubview:accessoryView_]; | |
91 } | |
92 | |
93 - (NSArray*)buttons { | |
94 return buttons_; | |
95 } | |
96 | |
97 - (NSButton*)closeButton { | |
98 return closeButton_; | |
99 } | |
100 | |
101 - (NSWindow*)window { | |
102 return window_; | |
103 } | |
104 | |
105 - (id)init { | |
106 if ((self = [super init])) { | |
107 window_.reset([[CWWindow alloc] | |
108 initWithContentRect:ui::kWindowSizeDeterminedLater]); | |
109 [window_ setReleasedWhenClosed:NO]; | |
110 NSView* content_view = [window_ contentView]; | |
111 | |
112 informativeTextField_ = CreateLabel(); | |
113 [content_view addSubview:informativeTextField_]; | |
114 messageTextField_ = CreateLabel(); | |
115 [content_view addSubview:messageTextField_]; | |
116 | |
117 closeButton_.reset([[HoverCloseButton alloc] initWithFrame:NSZeroRect]); | |
118 [content_view addSubview:closeButton_]; | |
119 } | |
120 return self; | |
121 } | |
122 | |
123 - (void)addButtonWithTitle:(NSString*)title | |
124 keyEquivalent:(NSString*)keyEquivalent { | |
125 if (!buttons_.get()) | |
126 buttons_.reset([[NSMutableArray alloc] init]); | |
127 NSButton* button = [[CWButton alloc] initWithFrame:NSZeroRect]; | |
128 [button setTitle:title]; | |
129 [button setKeyEquivalent:keyEquivalent]; | |
130 [buttons_ addObject:button]; | |
131 [[window_ contentView] addSubview:button]; | |
132 } | |
133 | |
134 - (void)layout { | |
135 // Button width | |
136 CGFloat buttonWidth = 0; | |
137 for (NSButton* button in buttons_.get()) { | |
138 [button sizeToFit]; | |
139 NSSize size = [button frame].size; | |
140 if (size.width < kButtonMinWidth) { | |
141 size.width = kButtonMinWidth; | |
142 [button setFrameSize:size]; | |
143 } | |
144 buttonWidth += size.width; | |
145 } | |
146 buttonWidth += ([buttons_ count] - 1) * kButtonGap; | |
147 | |
148 // Window width. | |
149 CGFloat windowWidth = buttonWidth; | |
150 if (accessoryView_.get()) | |
151 windowWidth = std::max(windowWidth, NSWidth([accessoryView_ frame])); | |
152 windowWidth += ConstrainedWindow::kHorizontalPadding * 2; | |
153 windowWidth = std::max(windowWidth, kWindowMinWidth); | |
154 | |
155 // Layout controls | |
156 [self layoutButtonsWithWindowWidth:windowWidth]; | |
157 CGFloat curY = NSMaxY([[buttons_ lastObject] frame]); | |
158 curY = [self layoutAccessoryViewAtYPos:curY]; | |
159 curY = [self layoutTextField:informativeTextField_ | |
160 yPos:curY | |
161 windowWidth:windowWidth]; | |
162 curY = [self layoutTextField:messageTextField_ | |
163 yPos:curY | |
164 windowWidth:windowWidth - kCloseButtonSize - kButtonGap]; | |
165 [self layoutCloseButtonWithWindowWidth:windowWidth]; | |
166 | |
167 // Update window frame | |
168 curY += ConstrainedWindow::kVerticalPadding; | |
169 [window_ setFrame:NSMakeRect(0, 0, windowWidth, curY) | |
170 display:NO]; | |
171 } | |
172 | |
173 - (void)layoutButtonsWithWindowWidth: (CGFloat)windowWidth { | |
174 // Layout first 2 button right to left. | |
175 CGFloat curX = windowWidth - ConstrainedWindow::kHorizontalPadding; | |
176 const int buttonCount = [buttons_ count]; | |
177 DCHECK_GE(buttonCount, 2); | |
178 for (int i = 0; i < 2; ++i) { | |
179 NSButton* button = [buttons_ objectAtIndex:i]; | |
180 NSRect rect = [button frame]; | |
181 rect.origin.x = curX - NSWidth(rect); | |
182 rect.origin.y = ConstrainedWindow::kVerticalPadding; | |
183 [button setFrameOrigin:rect.origin]; | |
184 curX = NSMinX(rect) - kButtonGap; | |
185 } | |
186 | |
187 // Layout remaining buttons left to right. | |
188 curX = ConstrainedWindow::kHorizontalPadding; | |
189 for (int i = buttonCount - 1; i >= 2; --i) { | |
190 NSButton* button = [buttons_ objectAtIndex:i]; | |
191 [button setFrameOrigin: | |
192 NSMakePoint(curX, ConstrainedWindow::kVerticalPadding)]; | |
193 curX += NSMaxX([button frame]) + kButtonGap; | |
194 } | |
195 } | |
196 | |
197 - (CGFloat)layoutTextField:(NSTextField*)textField | |
198 yPos:(CGFloat)yPos | |
199 windowWidth:(CGFloat)windowWidth { | |
200 if (![[textField stringValue] length]) { | |
201 [textField setHidden:YES]; | |
202 return yPos; | |
203 } | |
204 | |
205 [textField setHidden:NO]; | |
206 NSRect rect; | |
207 rect.size = CalculateDesiredSizeForWidth( | |
208 textField, windowWidth - ConstrainedWindow::kHorizontalPadding * 2); | |
209 rect.origin.y = yPos + ConstrainedWindow::kRowPadding; | |
210 rect.origin.x = ConstrainedWindow::kHorizontalPadding; | |
211 [textField setFrame:rect]; | |
212 return NSMaxY(rect); | |
213 } | |
214 | |
215 - (CGFloat)layoutAccessoryViewAtYPos:(CGFloat)yPos { | |
216 if (!accessoryView_.get()) | |
217 return yPos; | |
218 NSRect frame = [accessoryView_ frame]; | |
219 frame.origin.y = yPos + ConstrainedWindow::kRowPadding; | |
220 frame.origin.x = ConstrainedWindow::kHorizontalPadding; | |
221 [accessoryView_ setFrameOrigin:frame.origin]; | |
222 return NSMaxY(frame); | |
223 } | |
224 | |
225 - (void)layoutCloseButtonWithWindowWidth:(CGFloat)windowWidth { | |
226 NSRect frame; | |
227 frame.size.width = kCloseButtonSize; | |
228 frame.size.height = kCloseButtonSize; | |
229 frame.origin.x = | |
230 windowWidth - ConstrainedWindow::kHorizontalPadding - NSWidth(frame); | |
231 frame.origin.y = NSMaxY([messageTextField_ frame]) - NSHeight(frame); | |
232 [closeButton_ setFrame:frame]; | |
233 } | |
234 | |
235 @end | |
OLD | NEW |