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.
5 #import "chrome/browser/ui/cocoa/autofill/autofill_textfield.h"
10 #include "base/logging.h"
11 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
15 const CGFloat kGap = 6.0; // gap between icon and text.
16 const CGFloat kMinimumHeight = 27.0; // Enforced minimum height for text cells.
20 @interface AutofillTextFieldCell (Internal)
22 - (NSRect)iconFrameForFrame:(NSRect)frame;
23 - (NSRect)textFrameForFrame:(NSRect)frame;
27 @implementation AutofillTextField
29 @synthesize delegate = delegate_;
32 return [AutofillTextFieldCell class];
35 - (id)initWithFrame:(NSRect)frame {
36 if (self = [super initWithFrame:frame])
37 [super setDelegate:self];
41 - (BOOL)becomeFirstResponder {
42 BOOL result = [super becomeFirstResponder];
43 if (result && delegate_)
44 [delegate_ fieldBecameFirstResponder:self];
48 - (void)controlTextDidEndEditing:(NSNotification*)notification {
50 [delegate_ didEndEditing:self];
53 - (void)controlTextDidChange:(NSNotification*)aNotification {
55 [delegate_ didChange:self];
58 - (NSString*)fieldValue {
59 return [[self cell] fieldValue];
62 - (void)setFieldValue:(NSString*)fieldValue {
63 [[self cell] setFieldValue:fieldValue];
66 - (NSString*)defaultValue {
67 return [[self cell] defaultValue];
70 - (void)setDefaultValue:(NSString*)defaultValue {
71 [[self cell] setDefaultValue:defaultValue];
75 return [[[self cell] fieldValue] isEqualToString:[[self cell] defaultValue]];
78 - (NSString*)validityMessage {
79 return validityMessage_;
82 - (void)setValidityMessage:(NSString*)validityMessage {
83 validityMessage_.reset([validityMessage copy]);
84 [[self cell] setInvalid:[self invalid]];
88 return [validityMessage_ length] != 0;
93 @implementation AutofillTextFieldCell
95 @synthesize invalid = invalid_;
96 @synthesize defaultValue = defaultValue_;
98 - (void)setInvalid:(BOOL)invalid {
100 [[self controlView] setNeedsDisplay:YES];
107 - (void)setIcon:(NSImage*) icon {
108 icon_.reset([icon retain]);
109 [[self controlView] setNeedsDisplay:YES];
112 - (NSString*)fieldValue {
113 return [self stringValue];
116 - (void)setFieldValue:(NSString*)fieldValue {
117 [self setStringValue:fieldValue];
120 - (NSRect)textFrameForFrame:(NSRect)frame {
121 // Ensure text height is original cell height, and the text frame is centered
122 // vertically in the cell frame.
123 NSSize originalSize = [super cellSize];
124 if (originalSize.height < NSHeight(frame)) {
125 CGFloat delta = NSHeight(frame) - originalSize.height;
126 frame.origin.y += std::floor(delta / 2.0);
127 frame.size.height -= delta;
129 DCHECK_EQ(originalSize.height, NSHeight(frame));
132 NSRect textFrame, iconFrame;
133 NSDivideRect(frame, &iconFrame, &textFrame,
134 kGap + [icon_ size].width, NSMaxXEdge);
140 - (NSRect)iconFrameForFrame:(NSRect)frame {
144 NSDivideRect(frame, &iconFrame, &textFrame,
145 kGap + [icon_ size].width, NSMaxXEdge);
151 NSSize cellSize = [super cellSize];
154 NSSize iconSize = [icon_ size];
155 cellSize.width += kGap + iconSize.width;
156 cellSize.height = std::max(cellSize.height, iconSize.height);
158 cellSize.height = std::max(cellSize.height, kMinimumHeight);
162 - (void)editWithFrame:(NSRect)cellFrame
163 inView:(NSView *)controlView
164 editor:(NSText *)editor
165 delegate:(id)delegate
166 event:(NSEvent *)event {
167 [super editWithFrame:[self textFrameForFrame:cellFrame]
174 - (void)selectWithFrame:(NSRect)cellFrame
175 inView:(NSView *)controlView
176 editor:(NSText *)editor
177 delegate:(id)delegate
178 start:(NSInteger)start
179 length:(NSInteger)length {
180 [super selectWithFrame:[self textFrameForFrame:cellFrame]
188 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
189 NSRect textFrame = [self textFrameForFrame:cellFrame];
190 [super drawInteriorWithFrame:textFrame inView:controlView];
193 - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
194 [super drawWithFrame:cellFrame inView:controlView];
197 NSRect iconFrame = [self iconFrameForFrame:cellFrame];
198 iconFrame.size = [icon_ size];
199 iconFrame.origin.y +=
200 roundf((NSHeight(cellFrame) - NSHeight(iconFrame)) / 2.0);
201 [icon_ drawInRect:iconFrame
203 operation:NSCompositeSourceOver
210 gfx::ScopedNSGraphicsContextSaveGState state;
212 // Render red border for invalid fields.
213 [[NSColor colorWithDeviceRed:1.0 green:0.0 blue:0.0 alpha:1.0] setStroke];
214 [[NSBezierPath bezierPathWithRect:NSInsetRect(cellFrame, 0.5, 0.5)] stroke];