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

Side by Side 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: Encapsulate more, use native constructs more 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #import "chrome/browser/ui/cocoa/autofill/autofill_loading_shield_controller.h"
6
7 #include <cmath>
8
9 #include "base/strings/sys_string_conversions.h"
10 #include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h"
11 #include "chrome/browser/ui/autofill/loading_animation.h"
12 #include "ui/base/resource/resource_bundle.h"
13 #include "ui/gfx/animation/animation_delegate.h"
14
15 namespace {
16
17 // Horizontal spacing between the animated dots.
18 const CGFloat kDotsHorizontalPadding = 3;
19
20 } // namespace
21
22
23 // A C++ bridge class for driving the animation.
24 class AutofillLoadingAnimationBridge : public gfx::AnimationDelegate {
25 public:
26 AutofillLoadingAnimationBridge(AutofillLoadingShieldController* controller,
27 int font_size)
28 : animation_(this, font_size),
29 controller_(controller) {}
30 virtual ~AutofillLoadingAnimationBridge() {}
31
32 // gfx::AnimationDelegate implementation.
33 virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE {
34 DCHECK_EQ(animation, &animation_);
35 [controller_ relayoutDotsForSteppedAnimation:&animation_];
36 }
37
38 autofill::LoadingAnimation* animation() { return &animation_; }
39
40 private:
41 autofill::LoadingAnimation animation_;
42 AutofillLoadingShieldController* const controller_; // weak, owns |this|
43 };
44
45
46 @implementation AutofillLoadingShieldController
47
48 - (id)initWithDelegate:(autofill::AutofillDialogViewDelegate*)delegate {
49 if (self = [super initWithNibName:nil bundle:nil]) {
50 delegate_ = delegate;
51
52 gfx::Font font = ui::ResourceBundle::GetSharedInstance().
53 GetFont(ui::ResourceBundle::BaseFont).DeriveFont(8);
54 NSFont* native_font = font.GetNativeFont();
55 animationDriver_.reset(
56 new AutofillLoadingAnimationBridge(self, font.GetHeight()));
57
58 base::scoped_nsobject<NSBox> view([[NSBox alloc] initWithFrame:NSZeroRect]);
59 [view setBoxType:NSBoxCustom];
60 [view setBorderType:NSNoBorder];
61 [view setContentViewMargins:NSZeroSize];
62 [view setTitlePosition:NSNoTitle];
63
64 message_.reset([[NSTextField alloc] initWithFrame:NSZeroRect]);
65 [message_ setFont:native_font];
66 [message_ setEditable:NO];
67 [message_ setBordered:NO];
68 [message_ setDrawsBackground:NO];
69 [view addSubview:message_];
70
71 dots_.reset([[NSArray alloc] initWithArray:@[
72 [[NSTextField alloc] initWithFrame:NSZeroRect],
73 [[NSTextField alloc] initWithFrame:NSZeroRect],
74 [[NSTextField alloc] initWithFrame:NSZeroRect] ]]);
75 NSInteger tag = 0;
76 for (NSTextField* dot in dots_.get()) {
77 [dot setFont:native_font];
78 [dot setEditable:NO];
79 [dot setBordered:NO];
80 [dot setDrawsBackground:NO];
81 [dot setStringValue:@"."];
82 [dot setTag:tag];
83 [dot sizeToFit];
84 [view addSubview:dot];
85
86 ++tag;
87 }
88
89 [self setView:view];
90 }
91 return self;
92 }
93
94 - (void)update {
95 NSString* newMessage = @"";
96 if (delegate_->ShouldShowSpinner())
97 newMessage = base::SysUTF16ToNSString(delegate_->SpinnerText());
98
99 if ([newMessage isEqualToString:[message_ stringValue]])
100 return;
101
102 [message_ setStringValue:newMessage];
103 [message_ sizeToFit];
104
105 if ([newMessage length] > 0) {
106 [[self view] setHidden:NO];
107 animationDriver_->animation()->Start();
108 } else {
109 [[self view] setHidden:YES];
110 animationDriver_->animation()->Reset();
111 }
112
113 NSWindowController* delegate = [[[self view] window] windowController];
114 if ([delegate respondsToSelector:@selector(requestRelayout)])
115 [delegate performSelector:@selector(requestRelayout)];
116 }
117
118 - (NSSize)preferredSize {
119 NOTREACHED(); // Only implemented as part of AutofillLayout protocol.
120 return NSZeroSize;
121 }
122
123 - (void)performLayout {
124 if ([[self view] isHidden])
125 return;
126
127 NSRect bounds = [[self view] bounds];
128 NSRect messageFrame = [message_ frame];
129
130 CGFloat width = NSWidth(messageFrame);
groby-ooo-7-16 2013/11/16 01:34:59 NSSize size = messageFrame.size.
Ilya Sherman 2013/11/16 01:46:54 Done.
131 CGFloat height = NSHeight(messageFrame);
132 for (NSView* dot in dots_.get()) {
133 width += NSWidth([dot frame]) + kDotsHorizontalPadding;
134 height = std::max(height, NSHeight([dot frame]));
135 }
136
137 // The message + dots should be centered in the view.
138 messageFrame.origin.x = std::ceil((NSWidth(bounds) - width) / 2.0);
139 messageFrame.origin.y = std::ceil((NSHeight(bounds) - height) / 2.0);
140 [message_ setFrameOrigin:messageFrame.origin];
141
142 NSView* previousView = message_;
143 for (NSView* dot in dots_.get()) {
144 NSPoint dotFrameOrigin =
145 NSMakePoint(NSMaxX([previousView frame]) + kDotsHorizontalPadding,
146 messageFrame.origin.y);
147 [dot setFrameOrigin:dotFrameOrigin];
148
149 previousView = dot;
150 }
151 }
152
153 - (void)relayoutDotsForSteppedAnimation:(autofill::LoadingAnimation*)animation {
154 for (NSView* dot in dots_.get()) {
155 NSPoint origin = [dot frame].origin;
156 origin.y = [message_ frame].origin.y -
157 animationDriver_->animation()->GetCurrentValueForDot([dot tag]);
158 [dot setFrameOrigin:origin];
159 }
160 }
161
162 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698