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

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: Adopt new Blink interface Created 7 years, 8 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/base_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 kWindowPadding2x = 16;
Nico 2013/04/25 22:57:49 Not used, remove
tkent 2013/04/29 22:24:19 Done.
24 const CGFloat kIconTextMargin = 4;
25 const CGFloat kTextVerticalMargin = 4;
26
27 @interface ValidationMessageBubbleController : BaseBubbleController {
28 }
29
30 - (id)init:(NSWindow*)parent_window
31 anchoredAt:(NSPoint)anchor_point
32 mainText:(const string16&)main_text
33 subText:(const string16&)sub_text;
34
35 @end // interface ValidationMessageBubbleController
36
37
38 @implementation ValidationMessageBubbleController
39
40 - (id)init:(NSWindow*)parent_window
41 anchoredAt:(NSPoint)anchor_point
42 mainText:(const string16&)main_text
43 subText:(const string16&)sub_text {
44
45 scoped_nsobject<InfoBubbleWindow> window([[InfoBubbleWindow alloc]
46 initWithContentRect:
47 NSMakeRect(0, 0, kWindowInitialWidth, kWindowInitialHeight)
48 styleMask:NSBorderlessWindowMask
49 backing:NSBackingStoreBuffered
50 defer:NO]);
51 if ((self = [super initWithWindow:window.get()
52 parentWindow:parent_window
53 anchoredAt:anchor_point])) {
54 [[self bubble] setArrowLocation:info_bubble::kTopLeft];
55 self.shouldOpenKeyWindow = false;
56
57 NSRect content_frame = NSMakeRect(
58 kWindowPadding,
59 kWindowPadding,
60 kWindowInitialWidth - kWindowPadding * 2,
61 kWindowInitialHeight - (info_bubble::kBubbleArrowHeight
62 + kWindowPadding * 2));
63 scoped_nsobject<FlippedView> content_view(
64 [[FlippedView alloc] initWithFrame:content_frame]);
65 [[window contentView] addSubview:content_view];
66
67 NSImage* image = ResourceBundle::GetSharedInstance()
68 .GetNativeImageNamed(IDR_UPDATE_AVAILABLE).ToNSImage();
69 scoped_nsobject<NSImageView> image_view([[NSImageView alloc] initWithFrame:
Nico 2013/04/25 22:57:49 ObjC functions use camelCaseVariableNames (throug
tkent 2013/04/29 22:24:19 Renamed all of variables.
70 NSMakeRect(0, 0, image.size.width, image.size.height)]);
71 [image_view setImageFrameStyle:NSImageFrameNone];
72 [image_view setImage:image];
73 [content_view addSubview:image_view];
74 content_frame.size.height = image.size.height;
75
76 const CGFloat text_x = [image_view frame].size.width + kIconTextMargin;
Nico 2013/04/25 22:57:49 NSWidth([image_view frame])
tkent 2013/04/29 22:24:19 Replaced all of .size.width and .size.height with
77 NSRect text_frame =
78 NSMakeRect(text_x, 0, content_frame.size.width - text_x, 0);
79 scoped_nsobject<NSTextField> text(
80 [[NSTextField alloc] initWithFrame:text_frame]);
81 [text setStringValue:base::SysUTF16ToNSString(main_text)];
82 [text setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]];
83 [text setEditable:NO];
84 [text setBezeled:NO];
85 const CGFloat min_text_width
86 = kWindowMinWidth - kWindowPadding * 2 - text_x;
87 const CGFloat max_text_width
88 = kWindowMaxWidth - kWindowPadding * 2 - text_x;
89 [text sizeToFit];
90 [content_view addSubview:text];
91 text_frame = [text frame];
92 if (text_frame.size.width < min_text_width) {
93 text_frame.size.width = min_text_width;
94 [text setFrame:text_frame];
95 } else if (text_frame.size.width > max_text_width) {
96 text_frame.size.width = max_text_width;
97 text_frame.size.height = 0;
98 [text setFrame:text_frame];
99 text_frame.size.height =
100 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:text];
101 [text setFrame:text_frame];
102 }
103 content_frame.size.width = NSMaxX(text_frame);
104 content_frame.size.height = std::max(content_frame.size.height,
105 text_frame.size.height);
106
107 if (!sub_text.empty()) {
108 NSRect sub_text_frame = NSMakeRect(
109 text_x, NSMaxY(text_frame) + kTextVerticalMargin,
110 text_frame.size.width, 0);
111 scoped_nsobject<NSTextField> text2(
112 [[NSTextField alloc] initWithFrame:sub_text_frame]);
113 [text2 setStringValue:base::SysUTF16ToNSString(sub_text)];
114 [text2 setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
115 [text2 setEditable:NO];
116 [text2 setBezeled:NO];
117 [text2 sizeToFit];
118 sub_text_frame = [text2 frame];
119 if (sub_text_frame.size.width > max_text_width) {
120 sub_text_frame.size.width = max_text_width;
121 [text2 setFrame:sub_text_frame];
122 sub_text_frame.size.height =
123 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:text2];
124 [text2 setFrame:sub_text_frame];
125 }
126 [content_view addSubview:text2];
127 content_frame.size.width =
128 std::max(content_frame.size.width, NSMaxX(sub_text_frame));
129 content_frame.size.height =
130 std::max(content_frame.size.height, NSMaxY(sub_text_frame));
131 }
132
133 // Adjust the content and window size.
134 [content_view setFrame:content_frame];
135 NSRect window_frame = [window frame];
136 window_frame.size.width = content_frame.size.width + kWindowPadding * 2;
137 window_frame.size.height = content_frame.size.height + kWindowPadding * 2
138 + info_bubble::kBubbleArrowHeight;
139 [window setFrame:window_frame display:nil];
140
141 [self showWindow:nil];
142 }
143 return self;
144 }
145
146 @end // implementation ValidationMessageBubbleCocoa
147
148 // ----------------------------------------------------------------
149
150 namespace {
151
152 class ValidationMessageBubbleCocoa : public chrome::ValidationMessageBubble {
153 public:
154 ValidationMessageBubbleCocoa(content::RenderWidgetHost* widget_host,
155 const gfx::Rect& anchor_in_screen,
156 const string16& main_text,
157 const string16& sub_text) {
158 NSWindow* parent_window = [widget_host->GetView()->GetNativeView() window];
159 NSPoint anchor_point = NSMakePoint(
160 anchor_in_screen.x() + anchor_in_screen.width() / 2,
161 [[parent_window screen] frame].size.height
162 - (anchor_in_screen.y() + anchor_in_screen.height()));
163 controller_.reset([[[ValidationMessageBubbleController alloc]
164 init:parent_window
165 anchoredAt:anchor_point
166 mainText:main_text
167 subText:sub_text] retain]);
168 }
169
170 virtual ~ValidationMessageBubbleCocoa() {
171 [controller_.get() close];
172 }
173
174 private:
175 scoped_nsobject<ValidationMessageBubbleController> controller_;
176 };
177
178 }
179
180 // ----------------------------------------------------------------
181
182 namespace chrome {
183
184 scoped_ptr<ValidationMessageBubble> ValidationMessageBubble::CreateAndShow(
185 content::RenderWidgetHost* widget_host,
186 const gfx::Rect& anchor_in_screen,
187 const string16& main_text,
188 const string16& sub_text) {
189 return scoped_ptr<ValidationMessageBubble>(new ValidationMessageBubbleCocoa(
190 widget_host, anchor_in_screen, main_text, sub_text)).Pass();
191 }
192
193 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698