OLD | NEW |
---|---|
(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" | |
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
| |
10 #include "chrome/browser/ui/autofill/loading_animation.h" | |
11 #include "ui/base/resource/resource_bundle.h" | |
12 #include "ui/gfx/animation/animation_delegate.h" | |
13 | |
14 namespace { | |
15 | |
16 // Horizontal spacing between the animated dots. | |
17 const CGFloat kDotsHorizontalPadding = 3; | |
18 | |
19 } // namespace | |
20 | |
21 | |
22 // A C++ bridge class for driving the animation. | |
23 class AutofillLoadingAnimationBridge : public gfx::AnimationDelegate { | |
24 public: | |
25 AutofillLoadingAnimationBridge(AutofillLoadingShieldController* controller) | |
26 : animation_(this), | |
27 controller_(controller) {} | |
28 virtual ~AutofillLoadingAnimationBridge() {} | |
29 | |
30 // gfx::AnimationDelegate implementation. | |
31 virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE { | |
32 DCHECK_EQ(animation, &animation_); | |
33 [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.
| |
34 } | |
35 | |
36 autofill::LoadingAnimation* animation() { return &animation_; } | |
37 | |
38 private: | |
39 autofill::LoadingAnimation animation_; | |
40 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.
| |
41 }; | |
42 | |
43 | |
44 // A simple opaque view for drawing the background of the loading shield. | |
45 @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.
| |
46 @end | |
47 | |
48 @implementation AutofillOpaqueView | |
49 | |
50 - (BOOL)isOpaque { | |
51 return YES; | |
52 } | |
53 | |
54 - (void)drawRect:(NSRect)dirtyRect { | |
55 [[[self window] backgroundColor] setFill]; | |
56 [NSBezierPath fillRect:[self bounds]]; | |
57 } | |
58 | |
59 @end | |
60 | |
61 | |
62 @implementation AutofillLoadingShieldController | |
63 | |
64 - (id)init { | |
65 if (self = [super initWithNibName:nil bundle:nil]) { | |
66 animationDriver_.reset(new AutofillLoadingAnimationBridge(self)); | |
67 | |
68 base::scoped_nsobject<NSView> view( | |
69 [[AutofillOpaqueView alloc] initWithFrame:NSZeroRect]); | |
70 | |
71 message_.reset([[NSTextField alloc] initWithFrame:NSZeroRect]); | |
72 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
73 NSFont* font = | |
74 rb.GetFont(ui::ResourceBundle::BaseFont).DeriveFont(15).GetNativeFont(); | |
75 [message_ setFont:font]; | |
76 [message_ setEditable:NO]; | |
77 [message_ setBordered:NO]; | |
78 [message_ setDrawsBackground:NO]; | |
79 [view addSubview:message_]; | |
80 | |
81 dots_.reset([[NSArray alloc] initWithArray:@[ | |
82 [[NSTextField alloc] initWithFrame:NSZeroRect], | |
83 [[NSTextField alloc] initWithFrame:NSZeroRect], | |
84 [[NSTextField alloc] initWithFrame:NSZeroRect] ]]); | |
85 for (NSTextField* dot in dots_.get()) { | |
86 [dot setFont:font]; | |
87 [dot setEditable:NO]; | |
88 [dot setBordered:NO]; | |
89 [dot setDrawsBackground:NO]; | |
90 [dot setStringValue:@"."]; | |
91 [dot sizeToFit]; | |
92 [view addSubview:dot]; | |
93 } | |
94 | |
95 [self setView:view]; | |
96 } | |
97 return self; | |
98 } | |
99 | |
100 - (NSString*)message { | |
101 return [message_ stringValue]; | |
102 } | |
103 | |
104 - (void)setMessage:(NSString*)message { | |
105 [message_ setStringValue:message]; | |
106 [message_ sizeToFit]; | |
107 | |
108 if ([message length] > 0) | |
109 animationDriver_->animation()->Start(); | |
110 else | |
111 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
| |
112 } | |
113 | |
114 - (NSSize)preferredSize { | |
115 NOTREACHED(); // Only implemented as part of AutofillLayout protocol. | |
116 return NSZeroSize; | |
117 } | |
118 | |
119 - (void)performLayout { | |
120 if ([[self view] isHidden]) | |
121 return; | |
122 | |
123 NSRect bounds = [[self view] bounds]; | |
124 NSRect messageFrame = [message_ frame]; | |
125 | |
126 CGFloat width = NSWidth(messageFrame); | |
127 CGFloat height = NSHeight(messageFrame); | |
128 for (NSView* dot in dots_.get()) { | |
129 width += NSWidth([dot frame]) + kDotsHorizontalPadding; | |
130 height = std::max(height, NSHeight([dot frame])); | |
131 } | |
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
| |
132 | |
133 // The message + dots should be centered in the view. | |
134 messageFrame.origin.x = std::ceil((NSWidth(bounds) - width) / 2.0); | |
135 messageFrame.origin.y = std::ceil((NSHeight(bounds) - height) / 2.0); | |
136 [message_ setFrame:messageFrame]; | |
groby-ooo-7-16
2013/11/15 23:03:38
[message setFrameOrigin:...]
Ilya Sherman
2013/11/16 00:31:13
Done.
| |
137 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.
| |
138 NSView* dot = [dots_ objectAtIndex:i]; | |
139 NSView* previousView = i == 0 ? message_ : [dots_ objectAtIndex:i - 1]; | |
140 | |
141 NSPoint dotFrameOrigin = NSMakePoint( | |
142 NSMaxX([previousView frame]) + kDotsHorizontalPadding, | |
143 messageFrame.origin.y - | |
144 animationDriver_->animation()->GetCurrentValueForDot(i)); | |
145 [dot setFrameOrigin:dotFrameOrigin]; | |
146 } | |
147 } | |
148 | |
149 @end | |
OLD | NEW |