autofill_textfield.mm revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Copyright (c) 2013 The Chromium Authors. All rights reserved. 289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Use of this source code is governed by a BSD-style license that can be 389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// found in the LICENSE file. 489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#import "chrome/browser/ui/cocoa/autofill/autofill_textfield.h" 689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <algorithm> 889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" 1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace { 1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectconst CGFloat kGap = 6.0; // gap between icon and text. 1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} // namespace 1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project@interface AutofillTextFieldCell (Internal) 1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project- (NSRect)iconFrameForFrame:(NSRect)frame; 2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project- (NSRect)textFrameForFrame:(NSRect)frame; 217562408b2261d38415453378b6188f74fda99d88Mathias Agopian 2289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project@end 23c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 2489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project@implementation AutofillTextField 2589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 2664760240f931714858a59c1579f07264d7182ba2Dima Zavin+ (Class)cellClass { 27fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin return [AutofillTextFieldCell class]; 28c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent} 29c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 3089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project- (BOOL)invalid { 3189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return [[self cell] invalid]; 3289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 3389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project- (void)setInvalid:(BOOL)invalid { 3589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project [[self cell] setInvalid:invalid]; 3689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 3789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 38c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent- (NSString*)fieldValue { 39c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent return [[self cell] fieldValue]; 40c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent} 4189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project- (void)setFieldValue:(NSString*)fieldValue { 43fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin [[self cell] setFieldValue:fieldValue]; 4489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 4589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project@end 4789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project@implementation AutofillTextFieldCell 4989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 5089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project@synthesize invalid = invalid_; 5189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 5289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project- (NSImage*) icon{ 5389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return icon_; 5489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 5589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 5689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project- (void)setIcon:(NSImage*) icon { 5789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project icon_.reset([icon retain]); 5889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 595ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block 6089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project- (NSString*)fieldValue { 6189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return [self stringValue]; 6289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 6389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project- (void)setFieldValue:(NSString*)fieldValue { 6589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project [self setStringValue:fieldValue]; 6689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 6789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project- (NSRect)textFrameForFrame:(NSRect)frame { 6989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (icon_) { 7089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project NSRect textFrame, iconFrame; 7189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project NSDivideRect(frame, &iconFrame, &textFrame, 7289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project kGap + [icon_ size].width, NSMaxXEdge); 7329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block return textFrame; 7489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 75c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent return frame; 7689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 7789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 7889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project- (NSRect)iconFrameForFrame:(NSRect)frame { 7989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project NSRect iconFrame; 8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (icon_) { 8189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project NSRect textFrame; 8289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project NSDivideRect(frame, &iconFrame, &textFrame, 8389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project kGap + [icon_ size].width, NSMaxXEdge); 8489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 8589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return iconFrame; 8689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 8789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 8889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project- (NSSize)cellSize { 8989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project NSSize cellSize = [super cellSize]; 9089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 9189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (icon_) { 9289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project NSSize iconSize = [icon_ size]; 9389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project cellSize.width += kGap + iconSize.width; 9489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project cellSize.height = std::max(cellSize.height, iconSize.height); 9589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 9689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 9789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return cellSize; 9889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 9989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 10089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project- (void)editWithFrame:(NSRect)cellFrame 10189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project inView:(NSView *)controlView 10289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project editor:(NSText *)editor 10389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project delegate:(id)delegate 10489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project event:(NSEvent *)event { 10589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project [super editWithFrame:[self textFrameForFrame:cellFrame] 10689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project inView:controlView 10789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project editor:editor 10889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project delegate:delegate 10989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project event:event]; 11089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 11189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 11289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project- (void)selectWithFrame:(NSRect)cellFrame 11389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project inView:(NSView *)controlView 11489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project editor:(NSText *)editor 11589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project delegate:(id)delegate 11689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project start:(NSInteger)start 11789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project length:(NSInteger)length { 11889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project [super selectWithFrame:[self textFrameForFrame:cellFrame] 11989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project inView:controlView 12089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project editor:editor 12189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project delegate:delegate 12289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project start:start 123fa2877b9ea48baed934b866d2ab3658b69c4c869Eric Laurent length:length]; 12489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 125fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 12689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { 12789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project [super drawWithFrame:cellFrame inView:controlView]; 128c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 12989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (icon_) { 13089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project NSRect iconFrame = [self iconFrameForFrame:cellFrame]; 13189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project iconFrame.size = [icon_ size]; 13289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project iconFrame.origin.y += 13389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project roundf((NSHeight(cellFrame) - NSHeight(iconFrame)) / 2.0); 134fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin [icon_ drawInRect:iconFrame 13589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fromRect:NSZeroRect 13689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project operation:NSCompositeSourceOver 13789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fraction:1.0 13889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project respectFlipped:YES 13989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project hints:nil]; 14089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 141fa2877b9ea48baed934b866d2ab3658b69c4c869Eric Laurent 14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (invalid_) { 143fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin gfx::ScopedNSGraphicsContextSaveGState state; 14489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 14589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Render red border for invalid fields. 146c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent [[NSColor colorWithDeviceRed:1.0 green:0.0 blue:0.0 alpha:1.0] setStroke]; 14789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project [[NSBezierPath bezierPathWithRect:NSInsetRect(cellFrame, 0.5, 0.5)] stroke]; 14889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 14989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Render a dog ear to flag invalid fields. 15089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const CGFloat kDogEarSize = 10.0f; 15189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 152fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin // TODO(groby): This is a temporary placeholder and will be replaced 15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // with an image. (Pending UI/UX work). 15489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project [[NSColor colorWithDeviceRed:1.0 green:0.0 blue:0.0 alpha:1.0] setFill]; 15589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project NSBezierPath* dog_ear = [NSBezierPath bezierPath]; 15689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project NSPoint corner = NSMakePoint(NSMaxX(cellFrame), NSMinY(cellFrame)); 15789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project [dog_ear moveToPoint:NSMakePoint(corner.x - kDogEarSize, corner.y)]; 15889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project [dog_ear lineToPoint:corner]; 15989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project [dog_ear lineToPoint:NSMakePoint(corner.x, corner.y + kDogEarSize)]; 16089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project [dog_ear closePath]; 161930f4caa1e311ef7ff538c421a324396157eb24fGlenn Kasten [dog_ear fill]; 16289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 16389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 16489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 16589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project@end 16689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project