Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / dev_tools_controller.mm
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 "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/mac/scoped_ns_disable_screen_updates.h"
20 #include "ui/gfx/size_conversions.h"
21
22 using content::WebContents;
23
24 @interface DevToolsContainerView : BaseView {
25   DevToolsContentsResizingStrategy strategy_;
26
27   // Weak references. Ownership via -subviews.
28   NSView* devToolsView_;
29   NSView* contentsView_;
30 }
31
32 // Returns true iff layout has changed.
33 - (BOOL)setDevToolsView:(NSView*)devToolsView
34            withStrategy:(const DevToolsContentsResizingStrategy&)strategy;
35 - (void)adjustSubviews;
36 - (BOOL)hasDevToolsView;
37
38 @end
39
40
41 @implementation DevToolsContainerView
42
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_) {
48     if (contentsView_)
49       [contentsView_ setHidden:strategy.hide_inspected_contents()];
50     return strategy_changed;
51   }
52
53   if (devToolsView_) {
54     DCHECK_EQ(2u, [[self subviews] count]);
55     [devToolsView_ removeFromSuperview];
56     [contentsView_ setHidden:NO];
57     contentsView_ = nil;
58     devToolsView_ = nil;
59   }
60
61   if (devToolsView) {
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];
68
69     [contentsView_ setHidden:strategy.hide_inspected_contents()];
70   }
71
72   return YES;
73 }
74
75 - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize {
76   [self adjustSubviews];
77 }
78
79 - (BOOL)hasDevToolsView {
80   return devToolsView_ != nil;
81 }
82
83 - (void)adjustSubviews {
84   if (![[self subviews] count])
85     return;
86
87   if (!devToolsView_) {
88     DCHECK_EQ(1u, [[self subviews] count]);
89     NSView* contents = [[self subviews] objectAtIndex:0];
90     [contents setFrame:[self bounds]];
91     return;
92   }
93
94   DCHECK_EQ(2u, [[self subviews] count]);
95
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]];
103 }
104
105 @end
106
107
108 @implementation DevToolsController
109
110 - (id)init {
111   if ((self = [super init])) {
112     devToolsContainerView_.reset(
113         [[DevToolsContainerView alloc] initWithFrame:NSZeroRect]);
114     [devToolsContainerView_
115         setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
116   }
117   return self;
118 }
119
120 - (NSView*)view {
121   return devToolsContainerView_.get();
122 }
123
124 - (BOOL)updateDevToolsForWebContents:(WebContents*)contents
125                          withProfile:(Profile*)profile {
126   DevToolsContentsResizingStrategy strategy;
127   WebContents* devTools = DevToolsWindow::GetInTabWebContents(
128       contents, &strategy);
129
130   // Make sure we do not draw any transient arrangements of views.
131   gfx::ScopedNSDisableScreenUpdates disabler;
132
133   if (devTools && ![devToolsContainerView_ hasDevToolsView]) {
134     focusTracker_.reset(
135         [[FocusTracker alloc] initWithWindow:[devToolsContainerView_ window]]);
136   }
137
138   if (!devTools && [devToolsContainerView_ hasDevToolsView]) {
139     [focusTracker_ restoreFocusInWindow:[devToolsContainerView_ window]];
140     focusTracker_.reset();
141   }
142
143   NSView* devToolsView = nil;
144   if (devTools) {
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);
150
151     devTools->SetAllowOtherViews(true);
152     contents->SetAllowOtherViews(true);
153   } else {
154     contents->SetAllowOtherViews(false);
155   }
156
157   BOOL result = [devToolsContainerView_ setDevToolsView:devToolsView
158                                            withStrategy:strategy];
159   [devToolsContainerView_ adjustSubviews];
160   return result;
161 }
162
163 @end