• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 #include "chrome/browser/ui/views/frame/contents_container.h"
6 
7 #include "base/logging.h"
8 #include "third_party/skia/include/core/SkColor.h"
9 #include "ui/base/animation/slide_animation.h"
10 #include "views/background.h"
11 #include "views/widget/root_view.h"
12 #include "views/widget/widget.h"
13 
14 // Min/max opacity of the overlay.
15 static const int kMinOpacity = 0;
16 static const int kMaxOpacity = 192;
17 
18 // View used to track when the overlay widget is destroyed. If the
19 // ContentsContainer is still valid when the destructor is invoked this invokes
20 // |OverlayViewDestroyed| on the ContentsContainer.
21 class ContentsContainer::OverlayContentView : public views::View {
22  public:
OverlayContentView(ContentsContainer * container)23   explicit OverlayContentView(ContentsContainer* container)
24       : container_(container) {
25   }
~OverlayContentView()26   ~OverlayContentView() {
27     if (container_)
28       container_->OverlayViewDestroyed();
29   }
30 
Detach()31   void Detach() {
32     container_ = NULL;
33   }
34 
35  private:
36   ContentsContainer* container_;
37 
38   DISALLOW_COPY_AND_ASSIGN(OverlayContentView);
39 };
40 
ContentsContainer(views::View * active)41 ContentsContainer::ContentsContainer(views::View* active)
42     : active_(active),
43       preview_(NULL),
44       preview_tab_contents_(NULL),
45       active_overlay_(NULL),
46       overlay_view_(NULL),
47       active_top_margin_(0) {
48   AddChildView(active_);
49 }
50 
~ContentsContainer()51 ContentsContainer::~ContentsContainer() {
52   // We don't need to explicitly delete active_overlay_ as it'll be deleted by
53   // virtue of being a child window.
54   if (overlay_view_)
55     overlay_view_->Detach();
56 }
57 
MakePreviewContentsActiveContents()58 void ContentsContainer::MakePreviewContentsActiveContents() {
59   DCHECK(preview_);
60   RemoveFade();
61 
62   active_ = preview_;
63   preview_ = NULL;
64   Layout();
65 }
66 
SetPreview(views::View * preview,TabContents * preview_tab_contents)67 void ContentsContainer::SetPreview(views::View* preview,
68                                    TabContents* preview_tab_contents) {
69   if (preview == preview_)
70     return;
71 
72   if (preview_)
73     RemoveChildView(preview_);
74   preview_ = preview;
75   preview_tab_contents_ = preview_tab_contents;
76   if (preview_)
77     AddChildView(preview_);
78 
79   Layout();
80 }
81 
SetActiveTopMargin(int margin)82 void ContentsContainer::SetActiveTopMargin(int margin) {
83   if (active_top_margin_ == margin)
84     return;
85 
86   active_top_margin_ = margin;
87   // Make sure we layout next time around. We need this in case our bounds
88   // haven't changed.
89   InvalidateLayout();
90 }
91 
GetPreviewBounds()92 gfx::Rect ContentsContainer::GetPreviewBounds() {
93   gfx::Point screen_loc;
94   ConvertPointToScreen(this, &screen_loc);
95   return gfx::Rect(screen_loc, size());
96 }
97 
FadeActiveContents()98 void ContentsContainer::FadeActiveContents() {
99   if (active_overlay_ || !ui::Animation::ShouldRenderRichAnimation())
100     return;
101 
102 #if !defined(OS_WIN)
103   // TODO: fix this. I'm disabling as z-order isn't right on linux so that
104   // overlay ends up obscuring the omnibox.
105   return;
106 #endif
107 
108   overlay_animation_.reset(new ui::SlideAnimation(this));
109   overlay_animation_->SetDuration(300);
110   overlay_animation_->SetSlideDuration(300);
111   overlay_animation_->Show();
112 
113   CreateOverlay(kMinOpacity);
114 }
115 
ShowFade()116 void ContentsContainer::ShowFade() {
117   if (active_overlay_ || !ui::Animation::ShouldRenderRichAnimation())
118     return;
119 
120   CreateOverlay(kMaxOpacity);
121 }
122 
RemoveFade()123 void ContentsContainer::RemoveFade() {
124   overlay_animation_.reset();
125   if (active_overlay_) {
126     overlay_view_->Detach();
127     overlay_view_ = NULL;
128     active_overlay_->Close();
129     active_overlay_ = NULL;
130   }
131 }
132 
AnimationProgressed(const ui::Animation * animation)133 void ContentsContainer::AnimationProgressed(const ui::Animation* animation) {
134   active_overlay_->SetOpacity(
135       ui::Tween::ValueBetween(animation->GetCurrentValue(), kMinOpacity,
136                               kMaxOpacity));
137   active_overlay_->GetRootView()->SchedulePaint();
138 }
139 
Layout()140 void ContentsContainer::Layout() {
141   // The active view always gets the full bounds.
142   active_->SetBounds(0, active_top_margin_, width(),
143                      std::max(0, height() - active_top_margin_));
144 
145   if (preview_)
146     preview_->SetBounds(0, 0, width(), height());
147 
148   // Need to invoke views::View in case any views whose bounds didn't change
149   // still need a layout.
150   views::View::Layout();
151 }
152 
CreateOverlay(int initial_opacity)153 void ContentsContainer::CreateOverlay(int initial_opacity) {
154   DCHECK(!active_overlay_);
155   views::Widget::CreateParams params(views::Widget::CreateParams::TYPE_POPUP);
156   params.transparent = true;
157   params.accept_events = false;
158   active_overlay_ = views::Widget::CreateWidget(params);
159   active_overlay_->SetOpacity(initial_opacity);
160   gfx::Point screen_origin;
161   views::View::ConvertPointToScreen(active_, &screen_origin);
162   gfx::Rect overlay_bounds(screen_origin, active_->size());
163   active_overlay_->Init(active_->GetWidget()->GetNativeView(), overlay_bounds);
164   overlay_view_ = new OverlayContentView(this);
165   overlay_view_->set_background(
166       views::Background::CreateSolidBackground(SK_ColorWHITE));
167   active_overlay_->SetContentsView(overlay_view_);
168   active_overlay_->Show();
169   active_overlay_->MoveAboveWidget(active_->GetWidget());
170 }
171 
OverlayViewDestroyed()172 void ContentsContainer::OverlayViewDestroyed() {
173   active_overlay_ = NULL;
174   overlay_view_ = NULL;
175 }
176