Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Side by Side Diff: chrome/browser/ui/cocoa/validation_message_bubble_cocoa.mm

Issue 13160004: Re-implement form validation message UI with native widgets. (Common and Mac) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "base/memory/scoped_ptr.h"
6 #include "base/strings/sys_string_conversions.h"
7 #include "chrome/browser/ui/validation_message_bubble.h"
8 #include "content/public/browser/render_widget_host.h"
9 #include "content/public/browser/render_widget_host_view.h"
10 #include "grit/theme_resources.h"
11 #include "ui/base/resource/resource_bundle.h"
12 #import "chrome/browser/ui/cocoa/flipped_view.h"
13 #import "chrome/browser/ui/cocoa/info_bubble_view.h"
14 #import "chrome/browser/ui/cocoa/info_bubble_window.h"
15 #import "chrome/browser/ui/cocoa/validation_message_bubble_controller.h"
16 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
17
18 const CGFloat kWindowInitialWidth = 200;
19 const CGFloat kWindowInitialHeight = 100;
20 const CGFloat kWindowMinWidth = 64;
21 const CGFloat kWindowMaxWidth = 256;
22 const CGFloat kWindowPadding = 8;
23 const CGFloat kIconTextMargin = 4;
24 const CGFloat kTextVerticalMargin = 4;
25
26 @implementation ValidationMessageBubbleController
27
28 - (id)init:(NSWindow*)parentWindow
29 anchoredAt:(NSPoint)anchorPoint
30 mainText:(const string16&)mainText
31 subText:(const string16&)subText {
32
33 scoped_nsobject<InfoBubbleWindow> window([[InfoBubbleWindow alloc]
34 initWithContentRect:
35 NSMakeRect(0, 0, kWindowInitialWidth, kWindowInitialHeight)
36 styleMask:NSBorderlessWindowMask
37 backing:NSBackingStoreBuffered
38 defer:NO]);
39 if ((self = [super initWithWindow:window.get()
40 parentWindow:parentWindow
41 anchoredAt:anchorPoint])) {
42 [[self bubble] setArrowLocation:info_bubble::kTopLeft];
43 self.shouldOpenAsKeyWindow = NO;
44
45 NSView* contentView = [ValidationMessageBubbleController
46 constructContentView:mainText subText:subText];
47 [[window contentView] addSubview:contentView];
48 NSRect contentFrame = [contentView frame];
49 NSRect windowFrame = [window frame];
50 windowFrame.size.width = NSWidth(contentFrame) + kWindowPadding * 2;
51 windowFrame.size.height = NSHeight(contentFrame) + kWindowPadding * 2
52 + info_bubble::kBubbleArrowHeight;
53 [window setFrame:windowFrame display:nil];
54
55 [self showWindow:nil];
56 }
57 return self;
58 }
59
60 + (NSView*)constructContentView:(const string16&)mainText
61 subText:(const string16&)subText {
62 NSRect contentFrame = NSMakeRect(kWindowPadding, kWindowPadding, 0, 0);
63 FlippedView* contentView = [[FlippedView alloc] initWithFrame:contentFrame];
64
65 NSImage* image = ResourceBundle::GetSharedInstance()
66 .GetNativeImageNamed(IDR_INPUT_ALERT).ToNSImage();
67 scoped_nsobject<NSImageView> imageView([[NSImageView alloc]
68 initWithFrame:NSMakeRect(0, 0, image.size.width, image.size.height)]);
69 [imageView setImageFrameStyle:NSImageFrameNone];
70 [imageView setImage:image];
71 [contentView addSubview:imageView];
72 contentFrame.size.height = image.size.height;
73
74 const CGFloat textX = NSWidth([imageView frame]) + kIconTextMargin;
75 NSRect textFrame = NSMakeRect(textX, 0, NSWidth(contentFrame) - textX, 0);
76 scoped_nsobject<NSTextField> text(
77 [[NSTextField alloc] initWithFrame:textFrame]);
78 [text setStringValue:base::SysUTF16ToNSString(mainText)];
79 [text setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]];
80 [text setEditable:NO];
81 [text setBezeled:NO];
82 const CGFloat minTextWidth = kWindowMinWidth - kWindowPadding * 2 - textX;
83 const CGFloat maxTextWidth = kWindowMaxWidth - kWindowPadding * 2 - textX;
84 [text sizeToFit];
85 [contentView addSubview:text];
86 textFrame = [text frame];
87 if (NSWidth(textFrame) < minTextWidth) {
88 textFrame.size.width = minTextWidth;
89 [text setFrame:textFrame];
90 } else if (NSWidth(textFrame) > maxTextWidth) {
91 textFrame.size.width = maxTextWidth;
92 textFrame.size.height = 0;
93 [text setFrame:textFrame];
94 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:text];
95 textFrame = [text frame];
96 }
97 contentFrame.size.width = NSMaxX(textFrame);
98 contentFrame.size.height =
99 std::max(NSHeight(contentFrame), NSHeight(textFrame));
100
101 if (!subText.empty()) {
102 NSRect subTextFrame = NSMakeRect(
103 textX, NSMaxY(textFrame) + kTextVerticalMargin,
104 NSWidth(textFrame), 0);
105 scoped_nsobject<NSTextField> text2(
106 [[NSTextField alloc] initWithFrame:subTextFrame]);
107 [text2 setStringValue:base::SysUTF16ToNSString(subText)];
108 [text2 setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
109 [text2 setEditable:NO];
110 [text2 setBezeled:NO];
111 [text2 sizeToFit];
112 subTextFrame = [text2 frame];
113 if (NSWidth(subTextFrame) > maxTextWidth) {
114 subTextFrame.size.width = maxTextWidth;
115 [text2 setFrame:subTextFrame];
116 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:text2];
117 subTextFrame = [text2 frame];
118 }
119 [contentView addSubview:text2];
120 contentFrame.size.width =
121 std::max(NSWidth(contentFrame), NSMaxX(subTextFrame));
122 contentFrame.size.height =
123 std::max(NSHeight(contentFrame), NSMaxY(subTextFrame));
124 }
125
126 [contentView setFrame:contentFrame];
127 return contentView;
128 }
129
130
131 @end // implementation ValidationMessageBubbleCocoa
132
133 // ----------------------------------------------------------------
134
135 namespace {
136
137 class ValidationMessageBubbleCocoa : public chrome::ValidationMessageBubble {
138 public:
139 ValidationMessageBubbleCocoa(content::RenderWidgetHost* widget_host,
140 const gfx::Rect& anchor_in_screen,
141 const string16& main_text,
142 const string16& sub_text) {
143 NSWindow* parent_window = [widget_host->GetView()->GetNativeView() window];
144 NSPoint anchor_point = NSMakePoint(
145 anchor_in_screen.x() + anchor_in_screen.width() / 2,
146 NSHeight([[parent_window screen] frame])
147 - (anchor_in_screen.y() + anchor_in_screen.height()));
148 controller_.reset([[[ValidationMessageBubbleController alloc]
149 init:parent_window
150 anchoredAt:anchor_point
151 mainText:main_text
152 subText:sub_text] retain]);
153 }
154
155 virtual ~ValidationMessageBubbleCocoa() {
156 [controller_.get() close];
157 }
158
159 private:
160 scoped_nsobject<ValidationMessageBubbleController> controller_;
161 };
162
163 }
164
165 // ----------------------------------------------------------------
166
167 namespace chrome {
168
169 scoped_ptr<ValidationMessageBubble> ValidationMessageBubble::CreateAndShow(
170 content::RenderWidgetHost* widget_host,
171 const gfx::Rect& anchor_in_screen,
172 const string16& main_text,
173 const string16& sub_text) {
174 return scoped_ptr<ValidationMessageBubble>(new ValidationMessageBubbleCocoa(
175 widget_host, anchor_in_screen, main_text, sub_text)).Pass();
176 }
177
178 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/base_bubble_controller.mm ('k') | chrome/browser/ui/cocoa/validation_message_bubble_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698