• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4
5#import "chrome/browser/ui/cocoa/dev_tools_controller.h"
6
7#include <algorithm>
8#include <cmath>
9
10#include <Cocoa/Cocoa.h>
11
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"
22
23using content::WebContents;
24
25@interface DevToolsContainerView : BaseView {
26  DevToolsContentsResizingStrategy strategy_;
27
28  // Weak references. Ownership via -subviews.
29  NSView* devToolsView_;
30  NSView* contentsView_;
31}
32
33- (void)setDevToolsView:(NSView*)devToolsView
34           withStrategy:(const DevToolsContentsResizingStrategy&)strategy;
35- (void)adjustSubviews;
36- (BOOL)hasDevToolsView;
37
38@end
39
40
41@implementation DevToolsContainerView
42
43- (void)setDevToolsView:(NSView*)devToolsView
44           withStrategy:(const DevToolsContentsResizingStrategy&)strategy {
45  strategy_.CopyFrom(strategy);
46  if (devToolsView == devToolsView_) {
47    if (contentsView_)
48      [contentsView_ setHidden:strategy.hide_inspected_contents()];
49    return;
50  }
51
52  if (devToolsView_) {
53    DCHECK_EQ(2u, [[self subviews] count]);
54    [devToolsView_ removeFromSuperview];
55    [contentsView_ setHidden:NO];
56    contentsView_ = nil;
57    devToolsView_ = nil;
58  }
59
60  if (devToolsView) {
61    NSArray* subviews = [self subviews];
62    DCHECK_EQ(1u, [subviews count]);
63    contentsView_ = [subviews objectAtIndex:0];
64    devToolsView_ = devToolsView;
65    // Place DevTools under contents.
66    [self addSubview:devToolsView positioned:NSWindowBelow relativeTo:nil];
67
68    [contentsView_ setHidden:strategy.hide_inspected_contents()];
69  }
70}
71
72- (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize {
73  [self adjustSubviews];
74}
75
76- (BOOL)hasDevToolsView {
77  return devToolsView_ != nil;
78}
79
80- (void)adjustSubviews {
81  if (![[self subviews] count])
82    return;
83
84  if (!devToolsView_) {
85    DCHECK_EQ(1u, [[self subviews] count]);
86    NSView* contents = [[self subviews] objectAtIndex:0];
87    [contents setFrame:[self bounds]];
88    return;
89  }
90
91  DCHECK_EQ(2u, [[self subviews] count]);
92
93  gfx::Rect new_devtools_bounds;
94  gfx::Rect new_contents_bounds;
95  ApplyDevToolsContentsResizingStrategy(
96      strategy_, gfx::Size(NSSizeToCGSize([self bounds].size)),
97      &new_devtools_bounds, &new_contents_bounds);
98  [devToolsView_ setFrame:[self flipRectToNSRect:new_devtools_bounds]];
99  [contentsView_ setFrame:[self flipRectToNSRect:new_contents_bounds]];
100}
101
102@end
103
104
105@implementation DevToolsController
106
107- (id)init {
108  if ((self = [super init])) {
109    devToolsContainerView_.reset(
110        [[DevToolsContainerView alloc] initWithFrame:NSZeroRect]);
111    [devToolsContainerView_
112        setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
113  }
114  return self;
115}
116
117- (NSView*)view {
118  return devToolsContainerView_.get();
119}
120
121- (void)updateDevToolsForWebContents:(WebContents*)contents
122                         withProfile:(Profile*)profile {
123  DevToolsContentsResizingStrategy strategy;
124  WebContents* devTools = DevToolsWindow::GetInTabWebContents(
125      contents, &strategy);
126
127  // Make sure we do not draw any transient arrangements of views.
128  gfx::ScopedNSDisableScreenUpdates disabler;
129
130  if (devTools && ![devToolsContainerView_ hasDevToolsView]) {
131    focusTracker_.reset(
132        [[FocusTracker alloc] initWithWindow:[devToolsContainerView_ window]]);
133  }
134
135  if (!devTools && [devToolsContainerView_ hasDevToolsView]) {
136    [focusTracker_ restoreFocusInWindow:[devToolsContainerView_ window]];
137    focusTracker_.reset();
138  }
139
140  NSView* devToolsView = nil;
141  if (devTools) {
142    devToolsView = devTools->GetNativeView();
143    // |devToolsView| is a WebContentsViewCocoa object, whose ViewID was
144    // set to VIEW_ID_TAB_CONTAINER initially, so we need to change it to
145    // VIEW_ID_DEV_TOOLS_DOCKED here.
146    view_id_util::SetID(devToolsView, VIEW_ID_DEV_TOOLS_DOCKED);
147
148    devTools->SetAllowOtherViews(true);
149    contents->SetAllowOtherViews(true);
150  } else {
151    contents->SetAllowOtherViews(false);
152  }
153
154  [devToolsContainerView_ setDevToolsView:devToolsView withStrategy:strategy];
155  [devToolsContainerView_ adjustSubviews];
156}
157
158@end
159