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