Add ICU message format support
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / autofill / autofill_overlay_controller.mm
blobe0ff3ed2787394f4a1aeb946435412cb35aa2204
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
3 // found in the LICENSE file.
5 #import "chrome/browser/ui/cocoa/autofill/autofill_overlay_controller.h"
7 #include "base/logging.h"
8 #include "base/mac/foundation_util.h"
9 #include "base/strings/sys_string_conversions.h"
10 #include "chrome/browser/ui/autofill/autofill_dialog_types.h"
11 #include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h"
12 #include "chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h"
13 #include "skia/ext/skia_utils_mac.h"
15 namespace {
17 // Spacing around the message in the overlay view.
18 const CGFloat kOverlayLabelPadding = 34;
20 // Spacing below image and above text messages in overlay view.
21 const CGFloat kOverlayImageVerticalPadding = 90;
23 // TODO(groby): Unify colors with Views.
24 // Slight shading for mouse hover and legal document background.
25 SkColor kShadingColor = 0xfff2f2f2;
27 // A border color for the legal document view.
28 SkColor kSubtleBorderColor = 0xffdfdfdf;
30 }  // namespace
32 // An NSView encapsulating the message stack and its custom drawn elements.
33 @interface AutofillMessageView : NSView<AutofillLayout> {
34  @private
35   base::scoped_nsobject<NSTextField> label_;
38 - (id)initWithFrame:(NSRect)frame;
39 - (CGFloat)heightForWidth:(CGFloat)width;
40 - (void)setMessage:(const autofill::DialogOverlayString&)message;
41 @end
44 @implementation AutofillMessageView
46 - (void)drawRect:(NSRect)dirtyRect {
47   NSColor* shadingColor = gfx::SkColorToCalibratedNSColor(kShadingColor);
48   NSColor* borderColor = gfx::SkColorToCalibratedNSColor(kSubtleBorderColor);
50   CGFloat arrowHalfWidth = autofill::kArrowWidth / 2.0;
51   NSRect bounds = [self bounds];
52   CGFloat y = NSMaxY(bounds) - autofill::kArrowHeight;
54   NSBezierPath* arrow = [NSBezierPath bezierPath];
55   // Note that we purposely draw slightly outside of |bounds| so that the
56   // stroke is hidden on the sides and bottom.
57   NSRect arrowBounds = NSInsetRect(bounds, -1, -1);
58   arrowBounds.size.height--;
59   [arrow moveToPoint:NSMakePoint(NSMinX(arrowBounds), y)];
60   [arrow lineToPoint:
61       NSMakePoint(NSMidX(arrowBounds) - arrowHalfWidth, y)];
62   [arrow relativeLineToPoint:
63       NSMakePoint(arrowHalfWidth,autofill::kArrowHeight)];
64   [arrow relativeLineToPoint:
65       NSMakePoint(arrowHalfWidth, -autofill::kArrowHeight)];
66   [arrow lineToPoint:NSMakePoint(NSMaxX(arrowBounds), y)];
67   [arrow lineToPoint:NSMakePoint(NSMaxX(arrowBounds), NSMinY(arrowBounds))];
68   [arrow lineToPoint:NSMakePoint(NSMinX(arrowBounds), NSMinY(arrowBounds))];
69   [arrow closePath];
71   [shadingColor setFill];
72   [arrow fill];
73   [borderColor setStroke];
74   [arrow stroke];
77 - (id)initWithFrame:(NSRect)frame {
78   if (self = [super initWithFrame:frame]) {
79     label_.reset([[NSTextField alloc] initWithFrame:NSZeroRect]);
80     [label_ setEditable:NO];
81     [label_ setBordered:NO];
82     [label_ setDrawsBackground:NO];
83     [label_ setAlignment:NSCenterTextAlignment];
84     [self addSubview:label_];
85   }
86   return self;
89 - (CGFloat)heightForWidth:(CGFloat)width {
90   return NSHeight([label_ frame]) + autofill::kArrowHeight +
91       2 * kOverlayLabelPadding;
94 - (void)setMessage:(const autofill::DialogOverlayString&)message {
95   // We probably want to look at other multi-line messages somewhere.
96   [label_ setFont:message.font_list.GetPrimaryFont().GetNativeFont()];
97   [label_ setStringValue:base::SysUTF16ToNSString(message.text)];
98   [label_ setTextColor:[NSColor darkGrayColor]];
100   // Resize only height, preserve width. This guarantees text stays centered in
101   // the dialog.
102   NSSize labelSize = [label_ frame].size;
103   labelSize.height = [[label_ cell] cellSize].height;
104   [label_ setFrameSize:labelSize];
106   [self setHidden:message.text.empty()];
109 - (void)performLayout {
110   if ([self isHidden])
111     return;
113   CGFloat labelHeight = NSHeight([label_ frame]);
114   [label_ setFrame:NSMakeRect(0, kOverlayLabelPadding,
115                               NSWidth([self bounds]), labelHeight)];
116   // TODO(groby): useful DCHECK() goes here.
119 - (NSSize)preferredSize {
120   NOTREACHED();
121   return NSZeroSize;
124 @end
127 @implementation AutofillOverlayController
129 - (id)initWithDelegate:(autofill::AutofillDialogViewDelegate*)delegate {
130   if (self = [super initWithNibName:nil bundle:nil]) {
131     delegate_ = delegate;
133     messageView_.reset([[AutofillMessageView alloc] initWithFrame:NSZeroRect]);
134     imageView_.reset([[NSImageView alloc] initWithFrame:NSZeroRect]);
135     [imageView_ setImageAlignment:NSImageAlignCenter];
137     base::scoped_nsobject<NSView> view(
138         [[NSView alloc] initWithFrame:NSZeroRect]);
139     [view setSubviews:@[messageView_, imageView_]];
140     [self setView:view];
141   }
142   return self;
145 - (void)updateState {
146   const autofill::DialogOverlayState& state = delegate_->GetDialogOverlay();
148   if (state.image.IsEmpty()) {
149     [[self view] setHidden:YES];
150     return;
151   }
153   [[self view] setHidden:NO];
154   [imageView_ setImage:state.image.ToNSImage()];
155   [messageView_ setMessage:state.string];
157   NSWindowController* delegate = [[[self view] window] windowController];
158   if ([delegate respondsToSelector:@selector(requestRelayout)])
159     [delegate performSelector:@selector(requestRelayout)];
162 - (CGFloat)heightForWidth:(int)width {
163   return 2 * kOverlayImageVerticalPadding +
164       [messageView_ heightForWidth:width] +
165       [[imageView_ image] size].height;
168 - (NSSize)preferredSize {
169   NOTREACHED();  // Only implemented as part of AutofillLayout protocol.
170   return NSZeroSize;
173 - (void)performLayout {
174   NSRect bounds = [[self view] bounds];
176   int messageHeight = [messageView_ heightForWidth:NSWidth(bounds)];
177   [messageView_ setFrame:NSMakeRect(0, 0, NSWidth(bounds), messageHeight)];
178   [messageView_ performLayout];
180   NSSize imageSize = [[imageView_ image] size];
181   [imageView_ setFrame:NSMakeRect(
182        0, NSMaxY([messageView_ frame]) + kOverlayImageVerticalPadding,
183        NSWidth(bounds), imageSize.height)];
186 @end