blob: 97e005f42ee65c0935d506468e0e8892781ee5e5 [file] [log] [blame]
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "chrome/browser/ui/cocoa/autofill/autofill_textfield.h"
#include <algorithm>
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
namespace {
const CGFloat kGap = 6.0; // gap between icon and text.
} // namespace
@interface AutofillTextFieldCell (Internal)
- (NSRect)iconFrameForFrame:(NSRect)frame;
- (NSRect)textFrameForFrame:(NSRect)frame;
@end
@implementation AutofillTextField
@synthesize delegate = delegate_;
+ (Class)cellClass {
return [AutofillTextFieldCell class];
}
- (id)initWithFrame:(NSRect)frame {
if (self = [super initWithFrame:frame])
[super setDelegate:self];
return self;
}
- (BOOL)becomeFirstResponder {
BOOL result = [super becomeFirstResponder];
if (result && delegate_)
[delegate_ fieldBecameFirstResponder:self];
return result;
}
- (void)controlTextDidEndEditing:(NSNotification*)notification {
if (delegate_)
[delegate_ didEndEditing:self];
}
- (void)controlTextDidChange:(NSNotification*)aNotification {
if (delegate_)
[delegate_ didChange:self];
}
- (NSString*)fieldValue {
return [[self cell] fieldValue];
}
- (void)setFieldValue:(NSString*)fieldValue {
[[self cell] setFieldValue:fieldValue];
}
- (NSString*)validityMessage {
return validityMessage_;
}
- (void)setValidityMessage:(NSString*)validityMessage {
validityMessage_.reset([validityMessage copy]);
[[self cell] setInvalid:[self invalid]];
[self setNeedsDisplay:YES];
}
- (BOOL)invalid {
return [validityMessage_ length] != 0;
}
@end
@implementation AutofillTextFieldCell
@synthesize invalid = invalid_;
- (NSImage*) icon{
return icon_;
}
- (void)setIcon:(NSImage*) icon {
icon_.reset([icon retain]);
}
- (NSString*)fieldValue {
return [self stringValue];
}
- (void)setFieldValue:(NSString*)fieldValue {
[self setStringValue:fieldValue];
}
- (NSRect)textFrameForFrame:(NSRect)frame {
if (icon_) {
NSRect textFrame, iconFrame;
NSDivideRect(frame, &iconFrame, &textFrame,
kGap + [icon_ size].width, NSMaxXEdge);
return textFrame;
}
return frame;
}
- (NSRect)iconFrameForFrame:(NSRect)frame {
NSRect iconFrame;
if (icon_) {
NSRect textFrame;
NSDivideRect(frame, &iconFrame, &textFrame,
kGap + [icon_ size].width, NSMaxXEdge);
}
return iconFrame;
}
- (NSSize)cellSize {
NSSize cellSize = [super cellSize];
if (icon_) {
NSSize iconSize = [icon_ size];
cellSize.width += kGap + iconSize.width;
cellSize.height = std::max(cellSize.height, iconSize.height);
}
return cellSize;
}
- (void)editWithFrame:(NSRect)cellFrame
inView:(NSView *)controlView
editor:(NSText *)editor
delegate:(id)delegate
event:(NSEvent *)event {
[super editWithFrame:[self textFrameForFrame:cellFrame]
inView:controlView
editor:editor
delegate:delegate
event:event];
}
- (void)selectWithFrame:(NSRect)cellFrame
inView:(NSView *)controlView
editor:(NSText *)editor
delegate:(id)delegate
start:(NSInteger)start
length:(NSInteger)length {
[super selectWithFrame:[self textFrameForFrame:cellFrame]
inView:controlView
editor:editor
delegate:delegate
start:start
length:length];
}
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
[super drawWithFrame:cellFrame inView:controlView];
if (icon_) {
NSRect iconFrame = [self iconFrameForFrame:cellFrame];
iconFrame.size = [icon_ size];
iconFrame.origin.y +=
roundf((NSHeight(cellFrame) - NSHeight(iconFrame)) / 2.0);
[icon_ drawInRect:iconFrame
fromRect:NSZeroRect
operation:NSCompositeSourceOver
fraction:1.0
respectFlipped:YES
hints:nil];
}
if (invalid_) {
gfx::ScopedNSGraphicsContextSaveGState state;
// Render red border for invalid fields.
[[NSColor colorWithDeviceRed:1.0 green:0.0 blue:0.0 alpha:1.0] setStroke];
[[NSBezierPath bezierPathWithRect:NSInsetRect(cellFrame, 0.5, 0.5)] stroke];
// Render a dog ear to flag invalid fields.
const CGFloat kDogEarSize = 10.0f;
// TODO(groby): This is a temporary placeholder and will be replaced
// with an image. (Pending UI/UX work).
[[NSColor colorWithDeviceRed:1.0 green:0.0 blue:0.0 alpha:1.0] setFill];
NSBezierPath* dog_ear = [NSBezierPath bezierPath];
NSPoint corner = NSMakePoint(NSMaxX(cellFrame), NSMinY(cellFrame));
[dog_ear moveToPoint:NSMakePoint(corner.x - kDogEarSize, corner.y)];
[dog_ear lineToPoint:corner];
[dog_ear lineToPoint:NSMakePoint(corner.x, corner.y + kDogEarSize)];
[dog_ear closePath];
[dog_ear fill];
}
}
@end