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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/cocoa/validation_message_bubble_cocoa.mm
diff --git a/chrome/browser/ui/cocoa/validation_message_bubble_cocoa.mm b/chrome/browser/ui/cocoa/validation_message_bubble_cocoa.mm
new file mode 100644
index 0000000000000000000000000000000000000000..b2b3f1182193c499c04639c0312a1ce93259a625
--- /dev/null
+++ b/chrome/browser/ui/cocoa/validation_message_bubble_cocoa.mm
@@ -0,0 +1,193 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/sys_string_conversions.h"
+#include "chrome/browser/ui/validation_message_bubble.h"
+#include "content/public/browser/render_widget_host.h"
+#include "content/public/browser/render_widget_host_view.h"
+#include "grit/theme_resources.h"
+#include "ui/base/resource/resource_bundle.h"
+#import "chrome/browser/ui/cocoa/flipped_view.h"
+#import "chrome/browser/ui/cocoa/info_bubble_view.h"
+#import "chrome/browser/ui/cocoa/info_bubble_window.h"
+#import "chrome/browser/ui/cocoa/base_bubble_controller.h"
+#import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
+
+const CGFloat kWindowInitialWidth = 200;
+const CGFloat kWindowInitialHeight = 100;
+const CGFloat kWindowMinWidth = 64;
+const CGFloat kWindowMaxWidth = 256;
+const CGFloat kWindowPadding = 8;
+const CGFloat kWindowPadding2x = 16;
Nico 2013/04/25 22:57:49 Not used, remove
tkent 2013/04/29 22:24:19 Done.
+const CGFloat kIconTextMargin = 4;
+const CGFloat kTextVerticalMargin = 4;
+
+@interface ValidationMessageBubbleController : BaseBubbleController {
+}
+
+- (id)init:(NSWindow*)parent_window
+anchoredAt:(NSPoint)anchor_point
+ mainText:(const string16&)main_text
+ subText:(const string16&)sub_text;
+
+@end // interface ValidationMessageBubbleController
+
+
+@implementation ValidationMessageBubbleController
+
+- (id)init:(NSWindow*)parent_window
+anchoredAt:(NSPoint)anchor_point
+ mainText:(const string16&)main_text
+ subText:(const string16&)sub_text {
+
+ scoped_nsobject<InfoBubbleWindow> window([[InfoBubbleWindow alloc]
+ initWithContentRect:
+ NSMakeRect(0, 0, kWindowInitialWidth, kWindowInitialHeight)
+ styleMask:NSBorderlessWindowMask
+ backing:NSBackingStoreBuffered
+ defer:NO]);
+ if ((self = [super initWithWindow:window.get()
+ parentWindow:parent_window
+ anchoredAt:anchor_point])) {
+ [[self bubble] setArrowLocation:info_bubble::kTopLeft];
+ self.shouldOpenKeyWindow = false;
+
+ NSRect content_frame = NSMakeRect(
+ kWindowPadding,
+ kWindowPadding,
+ kWindowInitialWidth - kWindowPadding * 2,
+ kWindowInitialHeight - (info_bubble::kBubbleArrowHeight
+ + kWindowPadding * 2));
+ scoped_nsobject<FlippedView> content_view(
+ [[FlippedView alloc] initWithFrame:content_frame]);
+ [[window contentView] addSubview:content_view];
+
+ NSImage* image = ResourceBundle::GetSharedInstance()
+ .GetNativeImageNamed(IDR_UPDATE_AVAILABLE).ToNSImage();
+ 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.
+ NSMakeRect(0, 0, image.size.width, image.size.height)]);
+ [image_view setImageFrameStyle:NSImageFrameNone];
+ [image_view setImage:image];
+ [content_view addSubview:image_view];
+ content_frame.size.height = image.size.height;
+
+ 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
+ NSRect text_frame =
+ NSMakeRect(text_x, 0, content_frame.size.width - text_x, 0);
+ scoped_nsobject<NSTextField> text(
+ [[NSTextField alloc] initWithFrame:text_frame]);
+ [text setStringValue:base::SysUTF16ToNSString(main_text)];
+ [text setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]];
+ [text setEditable:NO];
+ [text setBezeled:NO];
+ const CGFloat min_text_width
+ = kWindowMinWidth - kWindowPadding * 2 - text_x;
+ const CGFloat max_text_width
+ = kWindowMaxWidth - kWindowPadding * 2 - text_x;
+ [text sizeToFit];
+ [content_view addSubview:text];
+ text_frame = [text frame];
+ if (text_frame.size.width < min_text_width) {
+ text_frame.size.width = min_text_width;
+ [text setFrame:text_frame];
+ } else if (text_frame.size.width > max_text_width) {
+ text_frame.size.width = max_text_width;
+ text_frame.size.height = 0;
+ [text setFrame:text_frame];
+ text_frame.size.height =
+ [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:text];
+ [text setFrame:text_frame];
+ }
+ content_frame.size.width = NSMaxX(text_frame);
+ content_frame.size.height = std::max(content_frame.size.height,
+ text_frame.size.height);
+
+ if (!sub_text.empty()) {
+ NSRect sub_text_frame = NSMakeRect(
+ text_x, NSMaxY(text_frame) + kTextVerticalMargin,
+ text_frame.size.width, 0);
+ scoped_nsobject<NSTextField> text2(
+ [[NSTextField alloc] initWithFrame:sub_text_frame]);
+ [text2 setStringValue:base::SysUTF16ToNSString(sub_text)];
+ [text2 setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
+ [text2 setEditable:NO];
+ [text2 setBezeled:NO];
+ [text2 sizeToFit];
+ sub_text_frame = [text2 frame];
+ if (sub_text_frame.size.width > max_text_width) {
+ sub_text_frame.size.width = max_text_width;
+ [text2 setFrame:sub_text_frame];
+ sub_text_frame.size.height =
+ [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:text2];
+ [text2 setFrame:sub_text_frame];
+ }
+ [content_view addSubview:text2];
+ content_frame.size.width =
+ std::max(content_frame.size.width, NSMaxX(sub_text_frame));
+ content_frame.size.height =
+ std::max(content_frame.size.height, NSMaxY(sub_text_frame));
+ }
+
+ // Adjust the content and window size.
+ [content_view setFrame:content_frame];
+ NSRect window_frame = [window frame];
+ window_frame.size.width = content_frame.size.width + kWindowPadding * 2;
+ window_frame.size.height = content_frame.size.height + kWindowPadding * 2
+ + info_bubble::kBubbleArrowHeight;
+ [window setFrame:window_frame display:nil];
+
+ [self showWindow:nil];
+ }
+ return self;
+}
+
+@end // implementation ValidationMessageBubbleCocoa
+
+// ----------------------------------------------------------------
+
+namespace {
+
+class ValidationMessageBubbleCocoa : public chrome::ValidationMessageBubble {
+ public:
+ ValidationMessageBubbleCocoa(content::RenderWidgetHost* widget_host,
+ const gfx::Rect& anchor_in_screen,
+ const string16& main_text,
+ const string16& sub_text) {
+ NSWindow* parent_window = [widget_host->GetView()->GetNativeView() window];
+ NSPoint anchor_point = NSMakePoint(
+ anchor_in_screen.x() + anchor_in_screen.width() / 2,
+ [[parent_window screen] frame].size.height
+ - (anchor_in_screen.y() + anchor_in_screen.height()));
+ controller_.reset([[[ValidationMessageBubbleController alloc]
+ init:parent_window
+ anchoredAt:anchor_point
+ mainText:main_text
+ subText:sub_text] retain]);
+ }
+
+ virtual ~ValidationMessageBubbleCocoa() {
+ [controller_.get() close];
+ }
+
+private:
+ scoped_nsobject<ValidationMessageBubbleController> controller_;
+};
+
+}
+
+// ----------------------------------------------------------------
+
+namespace chrome {
+
+scoped_ptr<ValidationMessageBubble> ValidationMessageBubble::CreateAndShow(
+ content::RenderWidgetHost* widget_host,
+ const gfx::Rect& anchor_in_screen,
+ const string16& main_text,
+ const string16& sub_text) {
+ return scoped_ptr<ValidationMessageBubble>(new ValidationMessageBubbleCocoa(
+ widget_host, anchor_in_screen, main_text, sub_text)).Pass();
+}
+
+}

Powered by Google App Engine
This is Rietveld 408576698