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

Unified Diff: chrome/browser/ui/cocoa/autofill/autofill_loading_shield_controller.mm

Issue 73723002: [rAc OSX] Animate the dots in the "Loading ..." message. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Clean up new files Created 7 years, 1 month 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/autofill/autofill_loading_shield_controller.mm
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_loading_shield_controller.mm b/chrome/browser/ui/cocoa/autofill/autofill_loading_shield_controller.mm
new file mode 100644
index 0000000000000000000000000000000000000000..bcc23c946b4b06d38fefe1dfc3721234aa5d08ba
--- /dev/null
+++ b/chrome/browser/ui/cocoa/autofill/autofill_loading_shield_controller.mm
@@ -0,0 +1,149 @@
+// Copyright 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.
+
+#import "chrome/browser/ui/cocoa/autofill/autofill_loading_shield_controller.h"
+
+#include <cmath>
+
+#include "base/strings/sys_string_conversions.h"
groby-ooo-7-16 2013/11/15 23:03:38 base/mac/scoped_nsobject.h
Ilya Sherman 2013/11/16 00:31:13 Already included in the header, and this #include
+#include "chrome/browser/ui/autofill/loading_animation.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/animation/animation_delegate.h"
+
+namespace {
+
+// Horizontal spacing between the animated dots.
+const CGFloat kDotsHorizontalPadding = 3;
+
+} // namespace
+
+
+// A C++ bridge class for driving the animation.
+class AutofillLoadingAnimationBridge : public gfx::AnimationDelegate {
+ public:
+ AutofillLoadingAnimationBridge(AutofillLoadingShieldController* controller)
+ : animation_(this),
+ controller_(controller) {}
+ virtual ~AutofillLoadingAnimationBridge() {}
+
+ // gfx::AnimationDelegate implementation.
+ virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE {
+ DCHECK_EQ(animation, &animation_);
+ [controller_ performLayout];
groby-ooo-7-16 2013/11/15 23:03:38 performLayoutWithAnimation: You always need the a
Ilya Sherman 2013/11/16 00:31:13 Done.
+ }
+
+ autofill::LoadingAnimation* animation() { return &animation_; }
+
+ private:
+ autofill::LoadingAnimation animation_;
+ AutofillLoadingShieldController* const controller_;
groby-ooo-7-16 2013/11/15 23:03:38 Probably worth pointing out it's not owned.
Ilya Sherman 2013/11/16 00:31:13 Done.
+};
+
+
+// A simple opaque view for drawing the background of the loading shield.
+@interface AutofillOpaqueView : NSView
groby-ooo-7-16 2013/11/15 23:03:38 Kill this, use NSBox. Needs a few items set: [box
Ilya Sherman 2013/11/16 00:31:13 Done.
+@end
+
+@implementation AutofillOpaqueView
+
+- (BOOL)isOpaque {
+ return YES;
+}
+
+- (void)drawRect:(NSRect)dirtyRect {
+ [[[self window] backgroundColor] setFill];
+ [NSBezierPath fillRect:[self bounds]];
+}
+
+@end
+
+
+@implementation AutofillLoadingShieldController
+
+- (id)init {
+ if (self = [super initWithNibName:nil bundle:nil]) {
+ animationDriver_.reset(new AutofillLoadingAnimationBridge(self));
+
+ base::scoped_nsobject<NSView> view(
+ [[AutofillOpaqueView alloc] initWithFrame:NSZeroRect]);
+
+ message_.reset([[NSTextField alloc] initWithFrame:NSZeroRect]);
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ NSFont* font =
+ rb.GetFont(ui::ResourceBundle::BaseFont).DeriveFont(15).GetNativeFont();
+ [message_ setFont:font];
+ [message_ setEditable:NO];
+ [message_ setBordered:NO];
+ [message_ setDrawsBackground:NO];
+ [view addSubview:message_];
+
+ dots_.reset([[NSArray alloc] initWithArray:@[
+ [[NSTextField alloc] initWithFrame:NSZeroRect],
+ [[NSTextField alloc] initWithFrame:NSZeroRect],
+ [[NSTextField alloc] initWithFrame:NSZeroRect] ]]);
+ for (NSTextField* dot in dots_.get()) {
+ [dot setFont:font];
+ [dot setEditable:NO];
+ [dot setBordered:NO];
+ [dot setDrawsBackground:NO];
+ [dot setStringValue:@"."];
+ [dot sizeToFit];
+ [view addSubview:dot];
+ }
+
+ [self setView:view];
+ }
+ return self;
+}
+
+- (NSString*)message {
+ return [message_ stringValue];
+}
+
+- (void)setMessage:(NSString*)message {
+ [message_ setStringValue:message];
+ [message_ sizeToFit];
+
+ if ([message length] > 0)
+ animationDriver_->animation()->Start();
+ else
+ animationDriver_->animation()->Reset();
groby-ooo-7-16 2013/11/15 23:03:38 You probably want a performLayout here. In general
Ilya Sherman 2013/11/16 00:31:13 This hides the shield, so there's not much reason
+}
+
+- (NSSize)preferredSize {
+ NOTREACHED(); // Only implemented as part of AutofillLayout protocol.
+ return NSZeroSize;
+}
+
+- (void)performLayout {
+ if ([[self view] isHidden])
+ return;
+
+ NSRect bounds = [[self view] bounds];
+ NSRect messageFrame = [message_ frame];
+
+ CGFloat width = NSWidth(messageFrame);
+ CGFloat height = NSHeight(messageFrame);
+ for (NSView* dot in dots_.get()) {
+ width += NSWidth([dot frame]) + kDotsHorizontalPadding;
+ height = std::max(height, NSHeight([dot frame]));
+ }
groby-ooo-7-16 2013/11/15 23:03:38 We should be able to compute this up front, in set
Ilya Sherman 2013/11/16 00:31:13 performLayout is now only ever called by the windo
+
+ // The message + dots should be centered in the view.
+ messageFrame.origin.x = std::ceil((NSWidth(bounds) - width) / 2.0);
+ messageFrame.origin.y = std::ceil((NSHeight(bounds) - height) / 2.0);
+ [message_ setFrame:messageFrame];
groby-ooo-7-16 2013/11/15 23:03:38 [message setFrameOrigin:...]
Ilya Sherman 2013/11/16 00:31:13 Done.
+ for (size_t i = 0; i < [dots_ count]; ++i) {
groby-ooo-7-16 2013/11/15 23:03:38 Avoid manual iteration over NSArray. You need the
Ilya Sherman 2013/11/16 00:31:13 Done.
+ NSView* dot = [dots_ objectAtIndex:i];
+ NSView* previousView = i == 0 ? message_ : [dots_ objectAtIndex:i - 1];
+
+ NSPoint dotFrameOrigin = NSMakePoint(
+ NSMaxX([previousView frame]) + kDotsHorizontalPadding,
+ messageFrame.origin.y -
+ animationDriver_->animation()->GetCurrentValueForDot(i));
+ [dot setFrameOrigin:dotFrameOrigin];
+ }
+}
+
+@end

Powered by Google App Engine
This is Rietveld 408576698