OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/ui/cocoa/autofill/autofill_notification_controller.h" | 5 #import "chrome/browser/ui/cocoa/autofill/autofill_notification_controller.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/mac/foundation_util.h" | 10 #include "base/mac/foundation_util.h" |
11 #include "base/mac/scoped_nsobject.h" | 11 #include "base/mac/scoped_nsobject.h" |
| 12 #include "base/strings/sys_string_conversions.h" |
| 13 #include "chrome/browser/ui/autofill/autofill_dialog_types.h" |
12 #include "chrome/browser/ui/chrome_style.h" | 14 #include "chrome/browser/ui/chrome_style.h" |
13 #include "chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h" | 15 #include "chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h" |
| 16 #include "grit/theme_resources.h" |
| 17 #include "skia/ext/skia_utils_mac.h" |
14 | 18 |
15 @interface AutofillNotificationView : NSView { | 19 @interface AutofillNotificationView : NSView { |
16 @private | 20 @private |
17 // Weak, determines anchor point for arrow. | 21 // Weak, determines anchor point for arrow. |
18 NSView* arrowAnchorView_; | 22 NSView* arrowAnchorView_; |
19 BOOL hasArrow_; | 23 BOOL hasArrow_; |
20 base::scoped_nsobject<NSColor> backgroundColor_; | 24 base::scoped_nsobject<NSColor> backgroundColor_; |
21 } | 25 } |
22 | 26 |
23 @property (nonatomic, assign) NSView* anchorView; | 27 @property (nonatomic, assign) NSView* anchorView; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 } | 65 } |
62 | 66 |
63 - (void)setBackgroundColor:(NSColor*)backgroundColor { | 67 - (void)setBackgroundColor:(NSColor*)backgroundColor { |
64 backgroundColor_.reset([backgroundColor retain]); | 68 backgroundColor_.reset([backgroundColor retain]); |
65 } | 69 } |
66 | 70 |
67 @end | 71 @end |
68 | 72 |
69 @implementation AutofillNotificationController | 73 @implementation AutofillNotificationController |
70 | 74 |
71 - (id)init { | 75 - (id)initWithNotification:(const autofill::DialogNotification*)notification { |
72 if (self = [super init]) { | 76 if (self = [super init]) { |
73 base::scoped_nsobject<AutofillNotificationView> view( | 77 base::scoped_nsobject<AutofillNotificationView> view( |
74 [[AutofillNotificationView alloc] initWithFrame:NSZeroRect]); | 78 [[AutofillNotificationView alloc] initWithFrame:NSZeroRect]); |
| 79 [view setBackgroundColor: |
| 80 gfx::SkColorToCalibratedNSColor(notification->GetBackgroundColor())]; |
75 [self setView:view]; | 81 [self setView:view]; |
76 | 82 |
77 textfield_.reset([[NSTextField alloc] initWithFrame:NSZeroRect]); | 83 textfield_.reset([[NSTextField alloc] initWithFrame:NSZeroRect]); |
78 [textfield_ setEditable:NO]; | 84 [textfield_ setEditable:NO]; |
79 [textfield_ setBordered:NO]; | 85 [textfield_ setBordered:NO]; |
80 [textfield_ setDrawsBackground:NO]; | 86 [textfield_ setDrawsBackground:NO]; |
| 87 [textfield_ setTextColor: |
| 88 gfx::SkColorToCalibratedNSColor(notification->GetTextColor())]; |
| 89 [textfield_ setStringValue: |
| 90 base::SysUTF16ToNSString(notification->display_text())]; |
| 91 [textfield_ setHidden:notification->HasCheckbox()]; |
81 | 92 |
82 checkbox_.reset([[NSButton alloc] initWithFrame:NSZeroRect]); | 93 checkbox_.reset([[NSButton alloc] initWithFrame:NSZeroRect]); |
83 [checkbox_ setButtonType:NSSwitchButton]; | 94 [checkbox_ setButtonType:NSSwitchButton]; |
84 [checkbox_ setHidden:YES]; | 95 [checkbox_ setHidden:!notification->HasCheckbox()]; |
85 [view setSubviews:@[textfield_, checkbox_]]; | 96 [checkbox_ setState:(notification->checked() ? NSOnState : NSOffState)]; |
| 97 [checkbox_ setAttributedTitle:[textfield_ attributedStringValue]]; |
| 98 // Update the size that preferredSizeForWidth will use. Do this here because |
| 99 // (1) preferredSizeForWidth is logically const, and so shouldn't have a |
| 100 // side-effect of updating the checkbox's frame, and |
| 101 // (2) this way, the sizing computation can be cached. |
| 102 [checkbox_ sizeToFit]; |
| 103 |
| 104 tooltipIcon_.reset([[NSImageView alloc] initWithFrame:NSZeroRect]); |
| 105 [tooltipIcon_ setImage: |
| 106 ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( |
| 107 IDR_AUTOFILL_TOOLTIP_ICON).ToNSImage()]; |
| 108 [tooltipIcon_ setFrameSize:[[tooltipIcon_ image] size]]; |
| 109 [tooltipIcon_ setToolTip: |
| 110 base::SysUTF16ToNSString(notification->tooltip_text())]; |
| 111 [tooltipIcon_ setHidden:[[tooltipIcon_ toolTip] length] == 0]; |
| 112 |
| 113 [view setSubviews:@[textfield_, checkbox_, tooltipIcon_]]; |
86 } | 114 } |
87 return self; | 115 return self; |
88 } | 116 } |
89 | 117 |
90 - (AutofillNotificationView*)notificationView { | 118 - (AutofillNotificationView*)notificationView { |
91 return base::mac::ObjCCastStrict<AutofillNotificationView>([self view]); | 119 return base::mac::ObjCCastStrict<AutofillNotificationView>([self view]); |
92 } | 120 } |
93 | 121 |
94 - (void)setHasArrow:(BOOL)hasArrow withAnchorView:(NSView*)anchorView { | 122 - (void)setHasArrow:(BOOL)hasArrow withAnchorView:(NSView*)anchorView { |
95 [[self notificationView] setAnchorView:anchorView]; | 123 [[self notificationView] setAnchorView:anchorView]; |
96 [[self notificationView] setHasArrow:hasArrow]; | 124 [[self notificationView] setHasArrow:hasArrow]; |
97 } | 125 } |
98 | 126 |
99 - (BOOL)hasArrow { | 127 - (BOOL)hasArrow { |
100 return [[self notificationView] hasArrow]; | 128 return [[self notificationView] hasArrow]; |
101 } | 129 } |
102 | 130 |
103 - (void)setHasCheckbox:(BOOL)hasCheckbox { | |
104 [checkbox_ setHidden:!hasCheckbox]; | |
105 [textfield_ setHidden:hasCheckbox]; | |
106 } | |
107 | |
108 - (NSString*)text { | |
109 return [textfield_ stringValue]; | |
110 } | |
111 | |
112 - (void)setText:(NSString*)string { | |
113 [textfield_ setStringValue:string]; | |
114 [checkbox_ setAttributedTitle:[textfield_ attributedStringValue]]; | |
115 | |
116 // Update the size that preferredSizeForWidth will use. Do this here because | |
117 // (1) preferredSizeForWidth is logically const, and so shouldn't have a | |
118 // side-effect of updating the checkbox's frame, and | |
119 // (2) this way, the sizing computation can be cached. | |
120 [checkbox_ sizeToFit]; | |
121 } | |
122 | |
123 - (NSTextField*)textfield { | 131 - (NSTextField*)textfield { |
124 return textfield_; | 132 return textfield_; |
125 } | 133 } |
126 | 134 |
127 - (NSButton*)checkbox { | 135 - (NSButton*)checkbox { |
128 return checkbox_; | 136 return checkbox_; |
129 } | 137 } |
130 | 138 |
131 - (NSColor*)backgroundColor { | 139 - (NSImageView*)tooltipIcon { |
132 return [[self notificationView] backgroundColor]; | 140 return tooltipIcon_; |
133 } | |
134 | |
135 - (void)setBackgroundColor:(NSColor*)backgroundColor { | |
136 [[self notificationView] setBackgroundColor:backgroundColor]; | |
137 } | |
138 | |
139 - (NSColor*)textColor { | |
140 return [textfield_ textColor]; | |
141 } | |
142 | |
143 - (void)setTextColor:(NSColor*)textColor { | |
144 [textfield_ setTextColor:textColor]; | |
145 } | 141 } |
146 | 142 |
147 - (NSSize)preferredSizeForWidth:(CGFloat)width { | 143 - (NSSize)preferredSizeForWidth:(CGFloat)width { |
| 144 width -= 2 * chrome_style::kHorizontalPadding; |
| 145 if (![tooltipIcon_ isHidden]) |
| 146 width -= [tooltipIcon_ frame].size.width + chrome_style::kHorizontalPadding; |
| 147 // TODO(isherman): Restore the DCHECK below once I figure out why it causes |
| 148 // unit tests to fail. |
| 149 //DCHECK_GT(width, 0); |
| 150 |
148 NSSize preferredSize; | 151 NSSize preferredSize; |
149 if (![textfield_ isHidden]) { | 152 if (![textfield_ isHidden]) { |
150 NSRect bounds = NSMakeRect(0, 0, width, CGFLOAT_MAX); | 153 NSRect bounds = NSMakeRect(0, 0, width, CGFLOAT_MAX); |
151 preferredSize = [[textfield_ cell] cellSizeForBounds:bounds]; | 154 preferredSize = [[textfield_ cell] cellSizeForBounds:bounds]; |
152 } else { | 155 } else { |
153 // Unlike textfields, checkboxes (NSButtons, really) are not designed to | 156 // Unlike textfields, checkboxes (NSButtons, really) are not designed to |
154 // support multi-line labels. Hence, ignore the |width| and simply use the | 157 // support multi-line labels. Hence, ignore the |width| and simply use the |
155 // size that fits fit the checkbox's contents. | 158 // size that fits fit the checkbox's contents. |
156 // NOTE: This logic will need to be updated if there is ever a need to | 159 // NOTE: This logic will need to be updated if there is ever a need to |
157 // support checkboxes with multi-line labels. | 160 // support checkboxes with multi-line labels. |
(...skipping 11 matching lines...) Expand all Loading... |
169 - (NSSize)preferredSize { | 172 - (NSSize)preferredSize { |
170 NOTREACHED(); | 173 NOTREACHED(); |
171 return NSZeroSize; | 174 return NSZeroSize; |
172 } | 175 } |
173 | 176 |
174 - (void)performLayout { | 177 - (void)performLayout { |
175 NSRect bounds = [[self view] bounds]; | 178 NSRect bounds = [[self view] bounds]; |
176 if ([[self notificationView] hasArrow]) | 179 if ([[self notificationView] hasArrow]) |
177 bounds.size.height -= autofill::kArrowHeight; | 180 bounds.size.height -= autofill::kArrowHeight; |
178 | 181 |
179 NSRect textFrame = NSInsetRect(bounds, | 182 // Calculate the frame size, leaving room for padding around the notification, |
| 183 // as well as for the tooltip if it is visible. |
| 184 NSRect labelFrame = NSInsetRect(bounds, |
180 chrome_style::kHorizontalPadding, | 185 chrome_style::kHorizontalPadding, |
181 autofill::kNotificationPadding); | 186 autofill::kNotificationPadding); |
182 NSControl* control = | 187 if (![tooltipIcon_ isHidden]) { |
183 [checkbox_ isHidden] ? textfield_.get() : checkbox_.get(); | 188 labelFrame.size.width -= |
184 [control setFrame:textFrame]; | 189 [tooltipIcon_ frame].size.width + chrome_style::kHorizontalPadding; |
| 190 } |
| 191 |
| 192 NSView* label = [checkbox_ isHidden] ? textfield_.get() : checkbox_.get(); |
| 193 [label setFrame:labelFrame]; |
| 194 |
| 195 if (![tooltipIcon_ isHidden]) { |
| 196 NSPoint tooltipOrigin = |
| 197 NSMakePoint( |
| 198 NSMaxX(labelFrame) + chrome_style::kHorizontalPadding, |
| 199 NSMidY(labelFrame) - (NSHeight([tooltipIcon_ frame]) / 2.0)); |
| 200 [tooltipIcon_ setFrameOrigin:tooltipOrigin]; |
| 201 } |
185 } | 202 } |
186 | 203 |
187 @end | 204 @end |
OLD | NEW |