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

Side by Side Diff: chrome/browser/ui/cocoa/infobar_container_controller.mm

Issue 6377001: [Mac] Organize all infobar files into chrome/browser/ui/cocoa/infobars/.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 11 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) 2010 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/logging.h"
6 #include "base/mac/mac_util.h"
7 #include "chrome/browser/tab_contents/infobar_delegate.h"
8 #include "chrome/browser/tab_contents/tab_contents.h"
9 #import "chrome/browser/ui/cocoa/animatable_view.h"
10 #include "chrome/browser/ui/cocoa/infobar.h"
11 #import "chrome/browser/ui/cocoa/infobar_container_controller.h"
12 #import "chrome/browser/ui/cocoa/infobar_controller.h"
13 #import "chrome/browser/ui/cocoa/view_id_util.h"
14 #include "chrome/common/notification_details.h"
15 #include "chrome/common/notification_source.h"
16 #include "skia/ext/skia_utils_mac.h"
17
18 // C++ class that receives INFOBAR_ADDED and INFOBAR_REMOVED
19 // notifications and proxies them back to |controller|.
20 class InfoBarNotificationObserver : public NotificationObserver {
21 public:
22 InfoBarNotificationObserver(InfoBarContainerController* controller)
23 : controller_(controller) {
24 }
25
26 private:
27 // NotificationObserver implementation
28 void Observe(NotificationType type,
29 const NotificationSource& source,
30 const NotificationDetails& details) {
31 switch (type.value) {
32 case NotificationType::TAB_CONTENTS_INFOBAR_ADDED:
33 [controller_ addInfoBar:Details<InfoBarDelegate>(details).ptr()
34 animate:YES];
35 break;
36 case NotificationType::TAB_CONTENTS_INFOBAR_REMOVED:
37 [controller_
38 closeInfoBarsForDelegate:Details<InfoBarDelegate>(details).ptr()
39 animate:YES];
40 break;
41 case NotificationType::TAB_CONTENTS_INFOBAR_REPLACED: {
42 typedef std::pair<InfoBarDelegate*, InfoBarDelegate*>
43 InfoBarDelegatePair;
44 InfoBarDelegatePair* delegates =
45 Details<InfoBarDelegatePair>(details).ptr();
46 [controller_
47 replaceInfoBarsForDelegate:delegates->first with:delegates->second];
48 break;
49 }
50 default:
51 NOTREACHED(); // we don't ask for anything else!
52 break;
53 }
54
55 [controller_ positionInfoBarsAndRedraw];
56 }
57
58 InfoBarContainerController* controller_; // weak, owns us.
59 };
60
61
62 @interface InfoBarContainerController (PrivateMethods)
63 // Returns the desired height of the container view, computed by
64 // adding together the heights of all its subviews.
65 - (CGFloat)desiredHeight;
66
67 @end
68
69
70 @implementation InfoBarContainerController
71 - (id)initWithResizeDelegate:(id<ViewResizer>)resizeDelegate {
72 DCHECK(resizeDelegate);
73 if ((self = [super initWithNibName:@"InfoBarContainer"
74 bundle:base::mac::MainAppBundle()])) {
75 resizeDelegate_ = resizeDelegate;
76 infoBarObserver_.reset(new InfoBarNotificationObserver(self));
77
78 // NSMutableArray needs an initial capacity, and we rarely ever see
79 // more than two infobars at a time, so that seems like a good choice.
80 infobarControllers_.reset([[NSMutableArray alloc] initWithCapacity:2]);
81 }
82 return self;
83 }
84
85 - (void)dealloc {
86 DCHECK([infobarControllers_ count] == 0);
87 view_id_util::UnsetID([self view]);
88 [super dealloc];
89 }
90
91 - (void)awakeFromNib {
92 // The info bar container view is an ordinary NSView object, so we set its
93 // ViewID here.
94 view_id_util::SetID([self view], VIEW_ID_INFO_BAR_CONTAINER);
95 }
96
97 - (void)removeDelegate:(InfoBarDelegate*)delegate {
98 DCHECK(currentTabContents_);
99 currentTabContents_->RemoveInfoBar(delegate);
100 }
101
102 - (void)removeController:(InfoBarController*)controller {
103 if (![infobarControllers_ containsObject:controller])
104 return;
105
106 // This code can be executed while InfoBarController is still on the stack, so
107 // we retain and autorelease the controller to prevent it from being
108 // dealloc'ed too early.
109 [[controller retain] autorelease];
110 [[controller view] removeFromSuperview];
111 [infobarControllers_ removeObject:controller];
112 [self positionInfoBarsAndRedraw];
113 }
114
115 - (void)changeTabContents:(TabContents*)contents {
116 registrar_.RemoveAll();
117 [self removeAllInfoBars];
118
119 currentTabContents_ = contents;
120 if (currentTabContents_) {
121 for (int i = 0; i < currentTabContents_->infobar_delegate_count(); ++i) {
122 [self addInfoBar:currentTabContents_->GetInfoBarDelegateAt(i)
123 animate:NO];
124 }
125
126 Source<TabContents> source(currentTabContents_);
127 registrar_.Add(infoBarObserver_.get(),
128 NotificationType::TAB_CONTENTS_INFOBAR_ADDED, source);
129 registrar_.Add(infoBarObserver_.get(),
130 NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, source);
131 registrar_.Add(infoBarObserver_.get(),
132 NotificationType::TAB_CONTENTS_INFOBAR_REPLACED, source);
133 }
134
135 [self positionInfoBarsAndRedraw];
136 }
137
138 - (void)tabDetachedWithContents:(TabContents*)contents {
139 if (currentTabContents_ == contents)
140 [self changeTabContents:NULL];
141 }
142
143 - (void)resizeView:(NSView*)view newHeight:(CGFloat)height {
144 NSRect frame = [view frame];
145 frame.size.height = height;
146 [view setFrame:frame];
147 [self positionInfoBarsAndRedraw];
148 }
149
150 - (void)setAnimationInProgress:(BOOL)inProgress {
151 if ([resizeDelegate_ respondsToSelector:@selector(setAnimationInProgress:)])
152 [resizeDelegate_ setAnimationInProgress:inProgress];
153 }
154
155 @end
156
157 @implementation InfoBarContainerController (PrivateMethods)
158
159 - (CGFloat)desiredHeight {
160 CGFloat height = 0;
161 for (InfoBarController* controller in infobarControllers_.get())
162 height += NSHeight([[controller view] frame]);
163 return height;
164 }
165
166 - (void)addInfoBar:(InfoBarDelegate*)delegate animate:(BOOL)animate {
167 scoped_ptr<InfoBar> infobar(delegate->CreateInfoBar());
168 InfoBarController* controller = infobar->controller();
169 [controller setContainerController:self];
170 [[controller animatableView] setResizeDelegate:self];
171 [[self view] addSubview:[controller view]];
172 [infobarControllers_ addObject:[controller autorelease]];
173
174 if (animate)
175 [controller animateOpen];
176 else
177 [controller open];
178 }
179
180 - (void)closeInfoBarsForDelegate:(InfoBarDelegate*)delegate
181 animate:(BOOL)animate {
182 for (InfoBarController* controller in
183 [NSArray arrayWithArray:infobarControllers_.get()]) {
184 if ([controller delegate] == delegate) {
185 [controller infobarWillClose];
186 if (animate)
187 [controller animateClosed];
188 else
189 [controller close];
190 }
191 }
192 }
193
194 - (void)replaceInfoBarsForDelegate:(InfoBarDelegate*)old_delegate
195 with:(InfoBarDelegate*)new_delegate {
196 [self closeInfoBarsForDelegate:old_delegate animate:NO];
197 [self addInfoBar:new_delegate animate:NO];
198 }
199
200 - (void)removeAllInfoBars {
201 for (InfoBarController* controller in infobarControllers_.get()) {
202 [[controller animatableView] stopAnimation];
203 [[controller view] removeFromSuperview];
204 }
205 [infobarControllers_ removeAllObjects];
206 }
207
208 - (void)positionInfoBarsAndRedraw {
209 NSRect containerBounds = [[self view] bounds];
210 int minY = 0;
211
212 // Stack the infobars at the bottom of the view, starting with the
213 // last infobar and working our way to the front of the array. This
214 // way we ensure that the first infobar added shows up on top, with
215 // the others below.
216 for (InfoBarController* controller in
217 [infobarControllers_ reverseObjectEnumerator]) {
218 NSView* view = [controller view];
219 NSRect frame = [view frame];
220 frame.origin.x = NSMinX(containerBounds);
221 frame.size.width = NSWidth(containerBounds);
222 frame.origin.y = minY;
223 minY += frame.size.height;
224 [view setFrame:frame];
225 }
226
227 [resizeDelegate_ resizeView:[self view] newHeight:[self desiredHeight]];
228 }
229
230 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698