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

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

Issue 11272015: DevTools: “Dock to right” broken after turning a tab into a window of its own. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review comments addressed. Created 8 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "chrome/browser/ui/cocoa/dev_tools_controller.h" 5 #import "chrome/browser/ui/cocoa/dev_tools_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include <Cocoa/Cocoa.h> 9 #include <Cocoa/Cocoa.h>
10 10
11 #include "chrome/browser/browser_process.h" 11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/prefs/pref_service.h" 12 #include "chrome/browser/prefs/pref_service.h"
13 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/tab_contents/tab_contents.h" 14 #include "chrome/browser/ui/tab_contents/tab_contents.h"
15 #import "chrome/browser/ui/cocoa/view_id_util.h" 15 #import "chrome/browser/ui/cocoa/view_id_util.h"
16 #include "chrome/common/pref_names.h" 16 #include "chrome/common/pref_names.h"
17 #include "content/public/browser/web_contents.h" 17 #include "content/public/browser/web_contents.h"
18 18
19 using content::WebContents; 19 using content::WebContents;
20 20
21 namespace {
22
23 // Minimal height of devtools pane or content pane when devtools are docked
24 // to the browser window.
25 const int kMinDevToolsHeight = 50;
26 const int kMinDevToolsWidth = 150;
27 const int kMinContentsSize = 50;
28
29 } // end namespace
30
31
32 @interface GraySplitView : NSSplitView 21 @interface GraySplitView : NSSplitView
33 - (NSColor*)dividerColor; 22 - (NSColor*)dividerColor;
34 @end 23 @end
35 24
36 25
37 @implementation GraySplitView 26 @implementation GraySplitView
38 - (NSColor*)dividerColor { 27 - (NSColor*)dividerColor {
39 return [NSColor darkGrayColor]; 28 return [NSColor darkGrayColor];
40 } 29 }
41 @end 30 @end
42 31
43 32
44 @interface DevToolsController (Private) 33 @interface DevToolsController (Private)
45 - (void)showDevToolsContainer:(NSView*)container 34 - (void)showDevToolsContainer;
46 dockSide:(DevToolsDockSide)dockSide 35 - (void)hideDevToolsContainer;
47 profile:(Profile*)profile; 36 - (void)updateDevToolsSplitPosition;
48 - (void)hideDevToolsContainer:(Profile*)profile;
49 - (void)setDockToRight:(BOOL)dock_to_right
50 withProfile:(Profile*)profile;
51 - (void)resizeDevTools:(CGFloat)size;
52 @end 37 @end
53 38
54 39
55 @implementation DevToolsController 40 @implementation DevToolsController
56 41
57 - (id)init { 42 - (id)init {
58 if ((self = [super init])) { 43 if ((self = [super init])) {
59 splitView_.reset([[GraySplitView alloc] initWithFrame:NSZeroRect]); 44 splitView_.reset([[GraySplitView alloc] initWithFrame:NSZeroRect]);
60 [splitView_ setDividerStyle:NSSplitViewDividerStyleThin]; 45 [splitView_ setDividerStyle:NSSplitViewDividerStyleThin];
61 [splitView_ setVertical:NO]; 46 [splitView_ setVertical:NO];
62 [splitView_ setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; 47 [splitView_ setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
63 [splitView_ setDelegate:self]; 48 [splitView_ setDelegate:self];
64 49
65 dockSide_ = DEVTOOLS_DOCK_SIDE_BOTTOM; 50 dockSide_ = DEVTOOLS_DOCK_SIDE_BOTTOM;
51 devToolsWindow_ = NULL;
66 } 52 }
67 return self; 53 return self;
68 } 54 }
69 55
70 - (void)dealloc { 56 - (void)dealloc {
71 [splitView_ setDelegate:nil]; 57 [splitView_ setDelegate:nil];
72 [super dealloc]; 58 [super dealloc];
73 } 59 }
74 60
75 - (NSView*)view { 61 - (NSView*)view {
76 return splitView_.get(); 62 return splitView_.get();
77 } 63 }
78 64
79 - (NSSplitView*)splitView { 65 - (NSSplitView*)splitView {
80 return splitView_.get(); 66 return splitView_.get();
81 } 67 }
82 68
83 - (void)updateDevToolsForWebContents:(WebContents*)contents 69 - (void)updateDevToolsForWebContents:(WebContents*)contents
84 withProfile:(Profile*)profile { 70 withProfile:(Profile*)profile {
85 // Get current devtools content. 71 // Get current devtools content.
yurys 2012/10/25 15:35:24 Outdated comment?
pfeldman 2012/10/25 16:14:42 Done.
86 DevToolsWindow* devToolsWindow = contents ? 72 DevToolsWindow* newDevToolsWindow = contents ?
87 DevToolsWindow::GetDockedInstanceForInspectedTab(contents) : NULL; 73 DevToolsWindow::GetDockedInstanceForInspectedTab(contents) : NULL;
88 WebContents* devToolsContents = devToolsWindow ?
89 devToolsWindow->tab_contents()->web_contents() : NULL;
90 74
91 if (devToolsContents && devToolsContents->GetNativeView() && 75 // Fast return in case of the same window having same orientation.
92 [devToolsContents->GetNativeView() superview] == splitView_.get()) { 76 if (devToolsWindow_ == newDevToolsWindow) {
93 [self setDockSide:devToolsWindow->dock_side() withProfile:profile]; 77 if (!newDevToolsWindow ||
94 return; 78 (newDevToolsWindow->dock_side() == dockSide_)) {
79 return;
80 }
95 } 81 }
96 82
97 NSArray* subviews = [splitView_ subviews]; 83 // Store last used position.
98 if (devToolsContents) { 84 if (devToolsWindow_) {
99 // |devToolsView| is a TabContentsViewCocoa object, whose ViewID was 85 NSArray* subviews = [splitView_ subviews];
100 // set to VIEW_ID_TAB_CONTAINER initially, so we need to change it to 86 NSView* devToolsView = [subviews objectAtIndex:1];
101 // VIEW_ID_DEV_TOOLS_DOCKED here. 87 if (dockSide_ == DEVTOOLS_DOCK_SIDE_RIGHT)
102 NSView* devToolsView = devToolsContents->GetNativeView(); 88 devToolsWindow_->SetWidth(NSWidth([devToolsView frame]));
103 view_id_util::SetID(devToolsView, VIEW_ID_DEV_TOOLS_DOCKED); 89 else
104 [self showDevToolsContainer:devToolsView 90 devToolsWindow_->SetHeight(NSHeight([devToolsView frame]));
105 dockSide:devToolsWindow->dock_side() 91 }
106 profile:profile]; 92
107 } else if ([subviews count] > 1) { 93 // Show / hide container if necessary. Changing dock orientation is
108 [self hideDevToolsContainer:profile]; 94 // hide + show.
95 bool shouldHide = devToolsWindow_ && (!newDevToolsWindow ||
96 dockSide_ != newDevToolsWindow->dock_side());
97 bool shouldShow = newDevToolsWindow && (!devToolsWindow_ || shouldHide);
98
99 if (shouldHide)
100 [self hideDevToolsContainer];
101
102 devToolsWindow_ = newDevToolsWindow;
103
104 if (shouldShow) {
105 dockSide_ = newDevToolsWindow->dock_side();
106 [self showDevToolsContainer];
107 } else if (newDevToolsWindow) {
108 [self updateDevToolsSplitPosition];
109 } 109 }
110 } 110 }
111 111
112 - (void)setDockSide:(DevToolsDockSide)dockSide 112 - (void)showDevToolsContainer {
113 withProfile:(Profile*)profile { 113 NSArray* subviews = [splitView_ subviews];
114 if (dockSide_ == dockSide) 114 DCHECK_EQ([subviews count], 1u);
115 return; 115 WebContents* devToolsContents =
116 devToolsWindow_->tab_contents()->web_contents();
116 117
117 NSArray* subviews = [splitView_ subviews]; 118 // |devToolsView| is a TabContentsViewCocoa object, whose ViewID was
118 if ([subviews count] == 2) { 119 // set to VIEW_ID_TAB_CONTAINER initially, so we need to change it to
119 scoped_nsobject<NSView> devToolsContentsView( 120 // VIEW_ID_DEV_TOOLS_DOCKED here.
120 [[subviews objectAtIndex:1] retain]); 121 NSView* devToolsView = devToolsContents->GetNativeView();
121 [self hideDevToolsContainer:profile]; 122 view_id_util::SetID(devToolsView, VIEW_ID_DEV_TOOLS_DOCKED);
122 dockSide_ = dockSide; 123 [splitView_ addSubview:devToolsView];
123 [self showDevToolsContainer:devToolsContentsView 124
124 dockSide:dockSide 125 bool isVertical = devToolsWindow_->dock_side() == DEVTOOLS_DOCK_SIDE_RIGHT;
125 profile:profile]; 126 [splitView_ setVertical:isVertical];
126 } else { 127 [self updateDevToolsSplitPosition];
127 dockSide_ = dockSide;
128 }
129 } 128 }
130 129
131 - (void)showDevToolsContainer:(NSView*)container 130 - (void)hideDevToolsContainer {
132 dockSide:(BOOL)dockSide
133 profile:(Profile*)profile {
134 NSArray* subviews = [splitView_ subviews]; 131 NSArray* subviews = [splitView_ subviews];
135 DCHECK_GE([subviews count], 1u); 132 DCHECK_EQ([subviews count], 2u);
136
137 CGFloat splitOffset = 0;
138
139 BOOL dockToRight = dockSide_ == DEVTOOLS_DOCK_SIDE_RIGHT;
140 CGFloat contentSize =
141 dockToRight ? NSWidth([splitView_ frame])
142 : NSHeight([splitView_ frame]);
143
144 if ([subviews count] == 1) {
145 // Load the default split offset.
146 splitOffset = profile->GetPrefs()->
147 GetInteger(dockToRight ? prefs::kDevToolsVSplitLocation :
148 prefs::kDevToolsHSplitLocation);
149
150 if (splitOffset < 0)
151 splitOffset = contentSize * 1 / 3;
152
153 [splitView_ addSubview:container];
154 } else {
155 DCHECK_EQ([subviews count], 2u);
156 // If devtools are already visible, keep the current size.
157 splitOffset = dockToRight ? NSWidth([[subviews objectAtIndex:1] frame])
158 : NSHeight([[subviews objectAtIndex:1] frame]);
159 [splitView_ replaceSubview:[subviews objectAtIndex:1]
160 with:container];
161 }
162
163 // Make sure |splitOffset| isn't too large or too small.
164 CGFloat minSize = dockToRight ? kMinDevToolsWidth: kMinDevToolsHeight;
165 splitOffset = std::max(minSize, splitOffset);
166 splitOffset = std::min(static_cast<CGFloat>(contentSize - kMinContentsSize),
167 splitOffset);
168
169 if (splitOffset < 0)
170 splitOffset = contentSize * 1 / 3;
171
172 DCHECK_GE(splitOffset, 0) << "kMinWebHeight needs to be smaller than "
173 << "smallest available tab contents space.";
174
175 [splitView_ setVertical: dockToRight];
176 [self resizeDevTools:splitOffset];
177 }
178
179 - (void)hideDevToolsContainer:(Profile*)profile {
180 NSArray* subviews = [splitView_ subviews];
181 NSView* oldDevToolsContentsView = [subviews objectAtIndex:1]; 133 NSView* oldDevToolsContentsView = [subviews objectAtIndex:1];
182
183 BOOL dockToRight = dockSide_ == DEVTOOLS_DOCK_SIDE_RIGHT;
184 // Store split offset when hiding devtools window only.
185 int splitOffset = dockToRight ? NSWidth([oldDevToolsContentsView frame])
186 : NSHeight([oldDevToolsContentsView frame]);
187 profile->GetPrefs()->SetInteger(
188 dockToRight ? prefs::kDevToolsVSplitLocation :
189 prefs::kDevToolsHSplitLocation,
190 splitOffset);
191
192 [oldDevToolsContentsView removeFromSuperview]; 134 [oldDevToolsContentsView removeFromSuperview];
193 [splitView_ adjustSubviews]; 135 [splitView_ adjustSubviews];
194 } 136 }
195 137
196 - (void)resizeDevTools:(CGFloat)size { 138 - (void)updateDevToolsSplitPosition {
197 NSArray* subviews = [splitView_ subviews]; 139 NSArray* subviews = [splitView_ subviews];
198 140
199 // It seems as if |-setPosition:ofDividerAtIndex:| should do what's needed, 141 // It seems as if |-setPosition:ofDividerAtIndex:| should do what's needed,
200 // but I can't figure out how to use it. Manually resize web and devtools. 142 // but I can't figure out how to use it. Manually resize web and devtools.
201 // TODO(alekseys): either make setPosition:ofDividerAtIndex: work or to add a 143 // TODO(alekseys): either make setPosition:ofDividerAtIndex: work or to add a
202 // category on NSSplitView to handle manual resizing. 144 // category on NSSplitView to handle manual resizing.
203 NSView* webView = [subviews objectAtIndex:0]; 145 NSView* webView = [subviews objectAtIndex:0];
204 NSRect webFrame = [webView frame]; 146 NSRect webFrame = [webView frame];
205 NSView* devToolsView = [subviews objectAtIndex:1]; 147 NSView* devToolsView = [subviews objectAtIndex:1];
206 NSRect devToolsFrame = [devToolsView frame]; 148 NSRect devToolsFrame = [devToolsView frame];
207 149
208 BOOL dockToRight = dockSide_ == DEVTOOLS_DOCK_SIDE_RIGHT; 150 if (devToolsWindow_->dock_side() == DEVTOOLS_DOCK_SIDE_RIGHT) {
209 if (dockToRight) 151 CGFloat size = devToolsWindow_->GetWidth(NSWidth([splitView_ frame]));
210 devToolsFrame.size.width = size; 152 devToolsFrame.size.width = size;
211 else
212 devToolsFrame.size.height = size;
213
214 if (dockToRight) {
215 webFrame.size.width = 153 webFrame.size.width =
216 NSWidth([splitView_ frame]) - ([splitView_ dividerThickness] + size); 154 NSWidth([splitView_ frame]) - ([splitView_ dividerThickness] + size);
217 } else { 155 } else {
156 CGFloat size = devToolsWindow_->GetHeight(NSHeight([splitView_ frame]));
157 devToolsFrame.size.height = size;
218 webFrame.size.height = 158 webFrame.size.height =
219 NSHeight([splitView_ frame]) - ([splitView_ dividerThickness] + size); 159 NSHeight([splitView_ frame]) - ([splitView_ dividerThickness] + size);
220 } 160 }
221 161
222 [webView setFrame:webFrame]; 162 [webView setFrame:webFrame];
223 [devToolsView setFrame:devToolsFrame]; 163 [devToolsView setFrame:devToolsFrame];
224 164
225 [splitView_ adjustSubviews]; 165 [splitView_ adjustSubviews];
226 } 166 }
227 167
228 // NSSplitViewDelegate protocol. 168 // NSSplitViewDelegate protocol.
229 - (BOOL)splitView:(NSSplitView *)splitView 169 - (BOOL)splitView:(NSSplitView *)splitView
230 shouldAdjustSizeOfSubview:(NSView *)subview { 170 shouldAdjustSizeOfSubview:(NSView *)subview {
231 // Return NO for the devTools view to indicate that it should not be resized 171 // Return NO for the devTools view to indicate that it should not be resized
232 // automatically. It preserves the height set by the user and also keeps 172 // automatically. It preserves the height set by the user and also keeps
233 // view height the same while changing tabs when one of the tabs shows infobar 173 // view height the same while changing tabs when one of the tabs shows infobar
234 // and others are not. 174 // and others are not.
235 if ([[splitView_ subviews] indexOfObject:subview] == 1) 175 if ([[splitView_ subviews] indexOfObject:subview] == 1)
236 return NO; 176 return NO;
237 return YES; 177 return YES;
238 } 178 }
239 179
240 -(void)splitViewWillResizeSubviews:(NSNotification *)notification { 180 -(void)splitViewWillResizeSubviews:(NSNotification *)notification {
241 [[splitView_ window] disableScreenUpdatesUntilFlush]; 181 [[splitView_ window] disableScreenUpdatesUntilFlush];
242 } 182 }
243 183
244 @end 184 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698