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
3 // found in the LICENSE file.
5 #import "chrome/browser/ui/cocoa/dev_tools_controller.h"
10 #include <Cocoa/Cocoa.h>
12 #include "base/prefs/pref_service.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/profiles/profile.h"
15 #import "chrome/browser/ui/cocoa/view_id_util.h"
16 #include "content/public/browser/web_contents.h"
17 #include "ui/base/cocoa/base_view.h"
18 #include "ui/base/cocoa/focus_tracker.h"
19 #include "ui/gfx/geometry/size_conversions.h"
20 #include "ui/gfx/mac/scoped_ns_disable_screen_updates.h"
22 using content::WebContents;
24 @interface DevToolsContainerView : BaseView {
25 DevToolsContentsResizingStrategy strategy_;
27 // Weak references. Ownership via -subviews.
28 NSView* devToolsView_;
29 NSView* contentsView_;
32 // Returns true iff layout has changed.
33 - (BOOL)setDevToolsView:(NSView*)devToolsView
34 withStrategy:(const DevToolsContentsResizingStrategy&)strategy;
35 - (void)adjustSubviews;
36 - (BOOL)hasDevToolsView;
41 @implementation DevToolsContainerView
43 - (BOOL)setDevToolsView:(NSView*)devToolsView
44 withStrategy:(const DevToolsContentsResizingStrategy&)strategy {
45 BOOL strategy_changed = !strategy_.Equals(strategy);
46 strategy_.CopyFrom(strategy);
47 if (devToolsView == devToolsView_) {
49 [contentsView_ setHidden:strategy.hide_inspected_contents()];
50 return strategy_changed;
54 DCHECK_EQ(2u, [[self subviews] count]);
55 [devToolsView_ removeFromSuperview];
56 [contentsView_ setHidden:NO];
62 NSArray* subviews = [self subviews];
63 DCHECK_EQ(1u, [subviews count]);
64 contentsView_ = [subviews objectAtIndex:0];
65 devToolsView_ = devToolsView;
66 // Place DevTools under contents.
67 [self addSubview:devToolsView positioned:NSWindowBelow relativeTo:nil];
69 [contentsView_ setHidden:strategy.hide_inspected_contents()];
75 - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize {
76 [self adjustSubviews];
79 - (BOOL)hasDevToolsView {
80 return devToolsView_ != nil;
83 - (void)adjustSubviews {
84 if (![[self subviews] count])
88 DCHECK_EQ(1u, [[self subviews] count]);
89 NSView* contents = [[self subviews] objectAtIndex:0];
90 [contents setFrame:[self bounds]];
94 DCHECK_EQ(2u, [[self subviews] count]);
96 gfx::Rect new_devtools_bounds;
97 gfx::Rect new_contents_bounds;
98 ApplyDevToolsContentsResizingStrategy(
99 strategy_, gfx::Size(NSSizeToCGSize([self bounds].size)),
100 &new_devtools_bounds, &new_contents_bounds);
101 [devToolsView_ setFrame:[self flipRectToNSRect:new_devtools_bounds]];
102 [contentsView_ setFrame:[self flipRectToNSRect:new_contents_bounds]];
108 @implementation DevToolsController
111 if ((self = [super init])) {
112 devToolsContainerView_.reset(
113 [[DevToolsContainerView alloc] initWithFrame:NSZeroRect]);
114 [devToolsContainerView_
115 setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
121 return devToolsContainerView_.get();
124 - (BOOL)updateDevToolsForWebContents:(WebContents*)contents
125 withProfile:(Profile*)profile {
126 DevToolsContentsResizingStrategy strategy;
127 WebContents* devTools = DevToolsWindow::GetInTabWebContents(
128 contents, &strategy);
130 // Make sure we do not draw any transient arrangements of views.
131 gfx::ScopedNSDisableScreenUpdates disabler;
133 if (devTools && ![devToolsContainerView_ hasDevToolsView]) {
135 [[FocusTracker alloc] initWithWindow:[devToolsContainerView_ window]]);
138 if (!devTools && [devToolsContainerView_ hasDevToolsView]) {
139 [focusTracker_ restoreFocusInWindow:[devToolsContainerView_ window]];
140 focusTracker_.reset();
143 NSView* devToolsView = nil;
145 devToolsView = devTools->GetNativeView();
146 // |devToolsView| is a WebContentsViewCocoa object, whose ViewID was
147 // set to VIEW_ID_TAB_CONTAINER initially, so we need to change it to
148 // VIEW_ID_DEV_TOOLS_DOCKED here.
149 view_id_util::SetID(devToolsView, VIEW_ID_DEV_TOOLS_DOCKED);
151 devTools->SetAllowOtherViews(true);
152 contents->SetAllowOtherViews(true);
154 contents->SetAllowOtherViews(false);
157 BOOL result = [devToolsContainerView_ setDevToolsView:devToolsView
158 withStrategy:strategy];
159 [devToolsContainerView_ adjustSubviews];