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

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

Issue 6358008: [Mac] Organize some files into chrome/browser/ui/cocoa/tab_contents/.... (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 #import "chrome/browser/ui/cocoa/tab_contents_controller.h"
6
7 #include "base/scoped_nsobject.h"
8 #include "chrome/browser/renderer_host/render_view_host.h"
9 #include "chrome/browser/renderer_host/render_widget_host_view.h"
10 #include "chrome/browser/tab_contents/navigation_controller.h"
11 #include "chrome/browser/tab_contents/tab_contents.h"
12 #include "chrome/common/notification_details.h"
13 #include "chrome/common/notification_observer.h"
14 #include "chrome/common/notification_registrar.h"
15 #include "chrome/common/notification_source.h"
16 #include "chrome/common/notification_type.h"
17
18
19 @interface TabContentsController(Private)
20 // Forwards frame update to |delegate_| (ResizeNotificationView calls it).
21 - (void)tabContentsViewFrameWillChange:(NSRect)frameRect;
22 // Notification from TabContents (forwarded by TabContentsNotificationBridge).
23 - (void)tabContentsRenderViewHostChanged:(RenderViewHost*)oldHost
24 newHost:(RenderViewHost*)newHost;
25 @end
26
27
28 // A supporting C++ bridge object to register for TabContents notifications.
29
30 class TabContentsNotificationBridge : public NotificationObserver {
31 public:
32 explicit TabContentsNotificationBridge(TabContentsController* controller);
33
34 // Overriden from NotificationObserver.
35 virtual void Observe(NotificationType type,
36 const NotificationSource& source,
37 const NotificationDetails& details);
38 // Register for |contents|'s notifications, remove all prior registrations.
39 void ChangeTabContents(TabContents* contents);
40 private:
41 NotificationRegistrar registrar_;
42 TabContentsController* controller_; // weak, owns us
43 };
44
45 TabContentsNotificationBridge::TabContentsNotificationBridge(
46 TabContentsController* controller)
47 : controller_(controller) {
48 }
49
50 void TabContentsNotificationBridge::Observe(
51 NotificationType type,
52 const NotificationSource& source,
53 const NotificationDetails& details) {
54 if (type == NotificationType::RENDER_VIEW_HOST_CHANGED) {
55 RenderViewHostSwitchedDetails* switched_details =
56 Details<RenderViewHostSwitchedDetails>(details).ptr();
57 [controller_ tabContentsRenderViewHostChanged:switched_details->old_host
58 newHost:switched_details->new_host];
59 } else {
60 NOTREACHED();
61 }
62 }
63
64 void TabContentsNotificationBridge::ChangeTabContents(TabContents* contents) {
65 registrar_.RemoveAll();
66 if (contents) {
67 registrar_.Add(this,
68 NotificationType::RENDER_VIEW_HOST_CHANGED,
69 Source<NavigationController>(&contents->controller()));
70 }
71 }
72
73
74 // A custom view that notifies |controller| that view's frame is changing.
75
76 @interface ResizeNotificationView : NSView {
77 TabContentsController* controller_;
78 }
79 - (id)initWithController:(TabContentsController*)controller;
80 @end
81
82 @implementation ResizeNotificationView
83
84 - (id)initWithController:(TabContentsController*)controller {
85 if ((self = [super initWithFrame:NSZeroRect])) {
86 controller_ = controller;
87 }
88 return self;
89 }
90
91 - (void)setFrame:(NSRect)frameRect {
92 [controller_ tabContentsViewFrameWillChange:frameRect];
93 [super setFrame:frameRect];
94 }
95
96 @end
97
98
99 @implementation TabContentsController
100 @synthesize tabContents = contents_;
101
102 - (id)initWithContents:(TabContents*)contents
103 delegate:(id<TabContentsControllerDelegate>)delegate {
104 if ((self = [super initWithNibName:nil bundle:nil])) {
105 contents_ = contents;
106 delegate_ = delegate;
107 tabContentsBridge_.reset(new TabContentsNotificationBridge(self));
108 tabContentsBridge_->ChangeTabContents(contents);
109 }
110 return self;
111 }
112
113 - (void)dealloc {
114 // make sure our contents have been removed from the window
115 [[self view] removeFromSuperview];
116 [super dealloc];
117 }
118
119 - (void)loadView {
120 scoped_nsobject<ResizeNotificationView> view(
121 [[ResizeNotificationView alloc] initWithController:self]);
122 [view setAutoresizingMask:NSViewHeightSizable|NSViewWidthSizable];
123 [self setView:view];
124 }
125
126 - (void)ensureContentsSizeDoesNotChange {
127 if (contents_) {
128 NSView* contentsContainer = [self view];
129 NSArray* subviews = [contentsContainer subviews];
130 if ([subviews count] > 0)
131 [contents_->GetNativeView() setAutoresizingMask:NSViewNotSizable];
132 }
133 }
134
135 // Call when the tab view is properly sized and the render widget host view
136 // should be put into the view hierarchy.
137 - (void)ensureContentsVisible {
138 if (!contents_)
139 return;
140 NSView* contentsContainer = [self view];
141 NSArray* subviews = [contentsContainer subviews];
142 NSView* contentsNativeView = contents_->GetNativeView();
143
144 NSRect contentsNativeViewFrame = [contentsContainer frame];
145 contentsNativeViewFrame.origin = NSZeroPoint;
146
147 [delegate_ tabContentsViewFrameWillChange:self
148 frameRect:contentsNativeViewFrame];
149
150 // Native view is resized to the actual size before it becomes visible
151 // to avoid flickering.
152 [contentsNativeView setFrame:contentsNativeViewFrame];
153 if ([subviews count] == 0) {
154 [contentsContainer addSubview:contentsNativeView];
155 } else if ([subviews objectAtIndex:0] != contentsNativeView) {
156 [contentsContainer replaceSubview:[subviews objectAtIndex:0]
157 with:contentsNativeView];
158 }
159 // Restore autoresizing properties possibly stripped by
160 // ensureContentsSizeDoesNotChange call.
161 [contentsNativeView setAutoresizingMask:NSViewWidthSizable|
162 NSViewHeightSizable];
163 }
164
165 - (void)changeTabContents:(TabContents*)newContents {
166 contents_ = newContents;
167 tabContentsBridge_->ChangeTabContents(contents_);
168 }
169
170 - (void)tabContentsViewFrameWillChange:(NSRect)frameRect {
171 [delegate_ tabContentsViewFrameWillChange:self frameRect:frameRect];
172 }
173
174 - (void)tabContentsRenderViewHostChanged:(RenderViewHost*)oldHost
175 newHost:(RenderViewHost*)newHost {
176 if (oldHost && newHost && oldHost->view() && newHost->view()) {
177 newHost->view()->set_reserved_contents_rect(
178 oldHost->view()->reserved_contents_rect());
179 } else {
180 [delegate_ tabContentsViewFrameWillChange:self
181 frameRect:[[self view] frame]];
182 }
183 }
184
185 - (void)willBecomeUnselectedTab {
186 // The RWHV is ripped out of the view hierarchy on tab switches, so it never
187 // formally resigns first responder status. Handle this by explicitly sending
188 // a Blur() message to the renderer, but only if the RWHV currently has focus.
189 RenderViewHost* rvh = [self tabContents]->render_view_host();
190 if (rvh && rvh->view() && rvh->view()->HasFocus())
191 rvh->Blur();
192 }
193
194 - (void)willBecomeSelectedTab {
195 // Do not explicitly call Focus() here, as the RWHV may not actually have
196 // focus (for example, if the omnibox has focus instead). The TabContents
197 // logic will restore focus to the appropriate view.
198 }
199
200 - (void)tabDidChange:(TabContents*)updatedContents {
201 // Calling setContentView: here removes any first responder status
202 // the view may have, so avoid changing the view hierarchy unless
203 // the view is different.
204 if ([self tabContents] != updatedContents) {
205 [self changeTabContents:updatedContents];
206 if ([self tabContents])
207 [self ensureContentsVisible];
208 }
209 }
210
211 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698