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

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: More 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;
Robert Sesek 2012/10/25 16:34:51 This will automatically be initialized to NULL in
pfeldman 2012/10/25 16:44:54 Done.
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 DevToolsWindow* newDevToolsWindow = contents ?
86 DevToolsWindow* devToolsWindow = contents ?
87 DevToolsWindow::GetDockedInstanceForInspectedTab(contents) : NULL; 72 DevToolsWindow::GetDockedInstanceForInspectedTab(contents) : NULL;
88 WebContents* devToolsContents = devToolsWindow ?
89 devToolsWindow->tab_contents()->web_contents() : NULL;
90 73
91 if (devToolsContents && devToolsContents->GetNativeView() && 74 // Fast return in case of the same window having same orientation.
92 [devToolsContents->GetNativeView() superview] == splitView_.get()) { 75 if (devToolsWindow_ == newDevToolsWindow) {
93 [self setDockSide:devToolsWindow->dock_side() withProfile:profile]; 76 if (!newDevToolsWindow ||
94 return; 77 (newDevToolsWindow->dock_side() == dockSide_)) {
78 return;
79 }
95 } 80 }
96 81
97 NSArray* subviews = [splitView_ subviews]; 82 // Store last used position.
98 if (devToolsContents) { 83 if (devToolsWindow_) {
99 // |devToolsView| is a TabContentsViewCocoa object, whose ViewID was 84 NSArray* subviews = [splitView_ subviews];
100 // set to VIEW_ID_TAB_CONTAINER initially, so we need to change it to 85 NSView* devToolsView = [subviews objectAtIndex:1];
Robert Sesek 2012/10/25 16:34:51 Should probably check the subviews count before ac
pfeldman 2012/10/25 16:44:54 Added DCHECK_EQ([subviews count], 2u);
101 // VIEW_ID_DEV_TOOLS_DOCKED here. 86 if (dockSide_ == DEVTOOLS_DOCK_SIDE_RIGHT)
102 NSView* devToolsView = devToolsContents->GetNativeView(); 87 devToolsWindow_->SetWidth(NSWidth([devToolsView frame]));
103 view_id_util::SetID(devToolsView, VIEW_ID_DEV_TOOLS_DOCKED); 88 else
104 [self showDevToolsContainer:devToolsView 89 devToolsWindow_->SetHeight(NSHeight([devToolsView frame]));
105 dockSide:devToolsWindow->dock_side() 90 }
106 profile:profile]; 91
107 } else if ([subviews count] > 1) { 92 // Show / hide container if necessary. Changing dock orientation is
108 [self hideDevToolsContainer:profile]; 93 // hide + show.
94 bool shouldHide = devToolsWindow_ && (!newDevToolsWindow ||
Robert Sesek 2012/10/25 16:34:51 Use ObjC BOOL
pfeldman 2012/10/25 16:44:54 Done.
95 dockSide_ != newDevToolsWindow->dock_side());
96 bool shouldShow = newDevToolsWindow && (!devToolsWindow_ || shouldHide);
97
98 if (shouldHide)
99 [self hideDevToolsContainer];
100
101 devToolsWindow_ = newDevToolsWindow;
102
103 if (shouldShow) {
104 dockSide_ = newDevToolsWindow->dock_side();
105 [self showDevToolsContainer];
106 } else if (newDevToolsWindow) {
107 [self updateDevToolsSplitPosition];
109 } 108 }
110 } 109 }
111 110
112 - (void)setDockSide:(DevToolsDockSide)dockSide 111 - (void)showDevToolsContainer {
113 withProfile:(Profile*)profile { 112 NSArray* subviews = [splitView_ subviews];
114 if (dockSide_ == dockSide) 113 DCHECK_EQ([subviews count], 1u);
115 return; 114 WebContents* devToolsContents =
115 devToolsWindow_->tab_contents()->web_contents();
116 116
117 NSArray* subviews = [splitView_ subviews]; 117 // |devToolsView| is a TabContentsViewCocoa object, whose ViewID was
118 if ([subviews count] == 2) { 118 // set to VIEW_ID_TAB_CONTAINER initially, so we need to change it to
119 scoped_nsobject<NSView> devToolsContentsView( 119 // VIEW_ID_DEV_TOOLS_DOCKED here.
120 [[subviews objectAtIndex:1] retain]); 120 NSView* devToolsView = devToolsContents->GetNativeView();
121 [self hideDevToolsContainer:profile]; 121 view_id_util::SetID(devToolsView, VIEW_ID_DEV_TOOLS_DOCKED);
122 dockSide_ = dockSide; 122 [splitView_ addSubview:devToolsView];
123 [self showDevToolsContainer:devToolsContentsView 123
124 dockSide:dockSide 124 bool isVertical = devToolsWindow_->dock_side() == DEVTOOLS_DOCK_SIDE_RIGHT;
Robert Sesek 2012/10/25 16:34:51 BOOL
pfeldman 2012/10/25 16:44:54 Done.
125 profile:profile]; 125 [splitView_ setVertical:isVertical];
126 } else { 126 [self updateDevToolsSplitPosition];
127 dockSide_ = dockSide;
128 }
129 } 127 }
130 128
131 - (void)showDevToolsContainer:(NSView*)container 129 - (void)hideDevToolsContainer {
132 dockSide:(BOOL)dockSide
133 profile:(Profile*)profile {
134 NSArray* subviews = [splitView_ subviews]; 130 NSArray* subviews = [splitView_ subviews];
135 DCHECK_GE([subviews count], 1u); 131 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]; 132 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]; 133 [oldDevToolsContentsView removeFromSuperview];
193 [splitView_ adjustSubviews]; 134 [splitView_ adjustSubviews];
194 } 135 }
195 136
196 - (void)resizeDevTools:(CGFloat)size { 137 - (void)updateDevToolsSplitPosition {
197 NSArray* subviews = [splitView_ subviews]; 138 NSArray* subviews = [splitView_ subviews];
198 139
199 // It seems as if |-setPosition:ofDividerAtIndex:| should do what's needed, 140 // 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. 141 // 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 142 // TODO(alekseys): either make setPosition:ofDividerAtIndex: work or to add a
202 // category on NSSplitView to handle manual resizing. 143 // category on NSSplitView to handle manual resizing.
203 NSView* webView = [subviews objectAtIndex:0]; 144 NSView* webView = [subviews objectAtIndex:0];
204 NSRect webFrame = [webView frame]; 145 NSRect webFrame = [webView frame];
205 NSView* devToolsView = [subviews objectAtIndex:1]; 146 NSView* devToolsView = [subviews objectAtIndex:1];
206 NSRect devToolsFrame = [devToolsView frame]; 147 NSRect devToolsFrame = [devToolsView frame];
207 148
208 BOOL dockToRight = dockSide_ == DEVTOOLS_DOCK_SIDE_RIGHT; 149 if (devToolsWindow_->dock_side() == DEVTOOLS_DOCK_SIDE_RIGHT) {
209 if (dockToRight) 150 CGFloat size = devToolsWindow_->GetWidth(NSWidth([splitView_ frame]));
210 devToolsFrame.size.width = size; 151 devToolsFrame.size.width = size;
211 else
212 devToolsFrame.size.height = size;
213
214 if (dockToRight) {
215 webFrame.size.width = 152 webFrame.size.width =
216 NSWidth([splitView_ frame]) - ([splitView_ dividerThickness] + size); 153 NSWidth([splitView_ frame]) - ([splitView_ dividerThickness] + size);
217 } else { 154 } else {
155 CGFloat size = devToolsWindow_->GetHeight(NSHeight([splitView_ frame]));
156 devToolsFrame.size.height = size;
218 webFrame.size.height = 157 webFrame.size.height =
219 NSHeight([splitView_ frame]) - ([splitView_ dividerThickness] + size); 158 NSHeight([splitView_ frame]) - ([splitView_ dividerThickness] + size);
220 } 159 }
221 160
222 [webView setFrame:webFrame]; 161 [webView setFrame:webFrame];
223 [devToolsView setFrame:devToolsFrame]; 162 [devToolsView setFrame:devToolsFrame];
224 163
225 [splitView_ adjustSubviews]; 164 [splitView_ adjustSubviews];
226 } 165 }
227 166
228 // NSSplitViewDelegate protocol. 167 // NSSplitViewDelegate protocol.
229 - (BOOL)splitView:(NSSplitView *)splitView 168 - (BOOL)splitView:(NSSplitView *)splitView
230 shouldAdjustSizeOfSubview:(NSView *)subview { 169 shouldAdjustSizeOfSubview:(NSView *)subview {
231 // Return NO for the devTools view to indicate that it should not be resized 170 // 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 171 // 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 172 // view height the same while changing tabs when one of the tabs shows infobar
234 // and others are not. 173 // and others are not.
235 if ([[splitView_ subviews] indexOfObject:subview] == 1) 174 if ([[splitView_ subviews] indexOfObject:subview] == 1)
236 return NO; 175 return NO;
237 return YES; 176 return YES;
238 } 177 }
239 178
240 -(void)splitViewWillResizeSubviews:(NSNotification *)notification { 179 -(void)splitViewWillResizeSubviews:(NSNotification *)notification {
241 [[splitView_ window] disableScreenUpdatesUntilFlush]; 180 [[splitView_ window] disableScreenUpdatesUntilFlush];
242 } 181 }
243 182
244 @end 183 @end
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/dev_tools_controller.h ('k') | chrome/browser/ui/gtk/browser_window_gtk.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698