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 "chrome/common/pref_names.h"
17 #include "content/public/browser/web_contents.h"
18 #include "ui/base/cocoa/base_view.h"
19 #include "ui/base/cocoa/focus_tracker.h"
20 #include "ui/gfx/mac/scoped_ns_disable_screen_updates.h"
21 #include "ui/gfx/size_conversions.h"
23 using content::WebContents;
25 @interface DevToolsContainerView : BaseView {
26 DevToolsContentsResizingStrategy strategy_;
28 // Weak references. Ownership via -subviews.
29 NSView* devToolsView_;
30 NSView* contentsView_;
33 - (void)setContentsResizingStrategy:
34 (const DevToolsContentsResizingStrategy&)strategy;
35 - (void)adjustSubviews;
36 - (void)showDevTools:(NSView*)devToolsView;
42 @implementation DevToolsContainerView
44 - (void)setContentsResizingStrategy:
45 (const DevToolsContentsResizingStrategy&)strategy {
46 strategy_.CopyFrom(strategy);
49 - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize {
50 [self adjustSubviews];
53 - (void)showDevTools:(NSView*)devToolsView {
54 NSArray* subviews = [self subviews];
55 DCHECK_EQ(1u, [subviews count]);
56 contentsView_ = [subviews objectAtIndex:0];
57 devToolsView_ = devToolsView;
58 // Place DevTools under contents.
59 [self addSubview:devToolsView positioned:NSWindowBelow relativeTo:nil];
62 - (void)hideDevTools {
63 DCHECK_EQ(2u, [[self subviews] count]);
64 [devToolsView_ removeFromSuperview];
69 - (void)adjustSubviews {
70 if (![[self subviews] count])
74 DCHECK_EQ(1u, [[self subviews] count]);
75 NSView* contents = [[self subviews] objectAtIndex:0];
76 [contents setFrame:[self bounds]];
80 DCHECK_EQ(2u, [[self subviews] count]);
82 gfx::Rect new_devtools_bounds;
83 gfx::Rect new_contents_bounds;
84 ApplyDevToolsContentsResizingStrategy(
85 strategy_, gfx::Size(NSSizeToCGSize([self bounds].size)),
86 [self flipNSRectToRect:[devToolsView_ bounds]],
87 [self flipNSRectToRect:[contentsView_ bounds]],
88 &new_devtools_bounds, &new_contents_bounds);
89 [devToolsView_ setFrame:[self flipRectToNSRect:new_devtools_bounds]];
90 [contentsView_ setFrame:[self flipRectToNSRect:new_contents_bounds]];
95 @interface DevToolsController (Private)
96 - (void)showDevToolsView;
97 - (void)hideDevToolsView;
101 @implementation DevToolsController
104 if ((self = [super init])) {
105 devToolsContainerView_.reset(
106 [[DevToolsContainerView alloc] initWithFrame:NSZeroRect]);
107 [devToolsContainerView_
108 setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
114 return devToolsContainerView_.get();
117 - (void)updateDevToolsForWebContents:(WebContents*)contents
118 withProfile:(Profile*)profile {
119 DevToolsContentsResizingStrategy strategy;
120 WebContents* devTools = DevToolsWindow::GetInTabWebContents(
121 contents, &strategy);
123 // Make sure we do not draw any transient arrangements of views.
124 gfx::ScopedNSDisableScreenUpdates disabler;
125 bool shouldHide = devTools_ && devTools_ != devTools;
126 bool shouldShow = devTools && devTools_ != devTools;
129 [self hideDevToolsView];
131 devTools_ = devTools;
133 devTools_->SetOverlayView(
135 gfx::Point(strategy.insets().left(), strategy.insets().top()));
136 [devToolsContainerView_ setContentsResizingStrategy:strategy];
138 DevToolsContentsResizingStrategy zeroStrategy;
139 [devToolsContainerView_ setContentsResizingStrategy:zeroStrategy];
143 [self showDevToolsView];
145 [devToolsContainerView_ adjustSubviews];
148 - (void)showDevToolsView {
150 [[FocusTracker alloc] initWithWindow:[devToolsContainerView_ window]]);
152 // |devToolsView| is a WebContentsViewCocoa object, whose ViewID was
153 // set to VIEW_ID_TAB_CONTAINER initially, so we need to change it to
154 // VIEW_ID_DEV_TOOLS_DOCKED here.
155 NSView* devToolsView = devTools_->GetNativeView();
156 view_id_util::SetID(devToolsView, VIEW_ID_DEV_TOOLS_DOCKED);
158 [devToolsContainerView_ showDevTools:devToolsView];
161 - (void)hideDevToolsView {
162 devTools_->RemoveOverlayView();
163 [devToolsContainerView_ hideDevTools];
164 [focusTracker_ restoreFocusInWindow:[devToolsContainerView_ window]];
165 focusTracker_.reset();