OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/views/frame/contents_container.h" | 5 #include "chrome/browser/views/frame/contents_container.h" |
6 | 6 |
7 #include "app/slide_animation.h" | 7 #include "app/slide_animation.h" |
| 8 #include "base/logging.h" |
8 #include "third_party/skia/include/core/SkColor.h" | 9 #include "third_party/skia/include/core/SkColor.h" |
9 #include "views/background.h" | 10 #include "views/background.h" |
10 #include "views/widget/root_view.h" | 11 #include "views/widget/root_view.h" |
11 #include "views/widget/widget.h" | 12 #include "views/widget/widget.h" |
12 | 13 |
13 // Min/max opacity of the overlay. | 14 // Min/max opacity of the overlay. |
14 static const int kMinOpacity = 0; | 15 static const int kMinOpacity = 0; |
15 static const int kMaxOpacity = 192; | 16 static const int kMaxOpacity = 192; |
16 | 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: |
| 23 explicit OverlayContentView(ContentsContainer* container) |
| 24 : container_(container) { |
| 25 } |
| 26 ~OverlayContentView() { |
| 27 if (container_) |
| 28 container_->OverlayViewDestroyed(); |
| 29 } |
| 30 |
| 31 void Detach() { |
| 32 container_ = NULL; |
| 33 } |
| 34 |
| 35 private: |
| 36 ContentsContainer* container_; |
| 37 |
| 38 DISALLOW_COPY_AND_ASSIGN(OverlayContentView); |
| 39 }; |
| 40 |
17 ContentsContainer::ContentsContainer(views::View* active) | 41 ContentsContainer::ContentsContainer(views::View* active) |
18 : active_(active), | 42 : active_(active), |
19 preview_(NULL), | 43 preview_(NULL), |
20 preview_tab_contents_(NULL), | 44 preview_tab_contents_(NULL), |
21 active_overlay_(NULL), | 45 active_overlay_(NULL), |
| 46 overlay_view_(NULL), |
22 active_top_margin_(0) { | 47 active_top_margin_(0) { |
23 AddChildView(active_); | 48 AddChildView(active_); |
24 } | 49 } |
25 | 50 |
26 ContentsContainer::~ContentsContainer() { | 51 ContentsContainer::~ContentsContainer() { |
27 // We don't need to explicitly delete active_overlay_ as it'll be deleted by | 52 // We don't need to explicitly delete active_overlay_ as it'll be deleted by |
28 // virtue of being a child window. | 53 // virtue of being a child window. |
| 54 if (overlay_view_) |
| 55 overlay_view_->Detach(); |
29 } | 56 } |
30 | 57 |
31 void ContentsContainer::MakePreviewContentsActiveContents() { | 58 void ContentsContainer::MakePreviewContentsActiveContents() { |
32 RemoveFade(); | 59 RemoveFade(); |
33 | 60 |
34 active_ = preview_; | 61 active_ = preview_; |
35 preview_ = NULL; | 62 preview_ = NULL; |
36 Layout(); | 63 Layout(); |
37 } | 64 } |
38 | 65 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 // TODO: fix this. I'm disabling as z-order isn't right on linux so that | 102 // TODO: fix this. I'm disabling as z-order isn't right on linux so that |
76 // overlay ends up obscuring the omnibox. | 103 // overlay ends up obscuring the omnibox. |
77 return; | 104 return; |
78 #endif | 105 #endif |
79 | 106 |
80 overlay_animation_.reset(new SlideAnimation(this)); | 107 overlay_animation_.reset(new SlideAnimation(this)); |
81 overlay_animation_->SetDuration(300); | 108 overlay_animation_->SetDuration(300); |
82 overlay_animation_->SetSlideDuration(300); | 109 overlay_animation_->SetSlideDuration(300); |
83 overlay_animation_->Show(); | 110 overlay_animation_->Show(); |
84 | 111 |
85 active_overlay_ = views::Widget::CreatePopupWidget(views::Widget::Transparent, | 112 CreateOverlay(kMinOpacity); |
86 views::Widget::NotAcceptEvents, | 113 } |
87 views::Widget::DeleteOnDestroy, | 114 |
88 views::Widget::MirrorOriginInRTL); | 115 void ContentsContainer::ShowFade() { |
89 active_overlay_->SetOpacity(0); | 116 if (active_overlay_ || !Animation::ShouldRenderRichAnimation()) |
90 gfx::Point screen_origin; | 117 return; |
91 views::View::ConvertPointToScreen(active_, &screen_origin); | 118 |
92 gfx::Rect overlay_bounds(screen_origin, active_->size()); | 119 CreateOverlay(kMaxOpacity); |
93 active_overlay_->Init(active_->GetWidget()->GetNativeView(), overlay_bounds); | |
94 views::View* content_view = new views::View(); | |
95 content_view->set_background( | |
96 views::Background::CreateSolidBackground(SK_ColorWHITE)); | |
97 active_overlay_->SetContentsView(content_view); | |
98 active_overlay_->Show(); | |
99 active_overlay_->MoveAbove(active_->GetWidget()); | |
100 } | 120 } |
101 | 121 |
102 void ContentsContainer::RemoveFade() { | 122 void ContentsContainer::RemoveFade() { |
103 overlay_animation_.reset(); | 123 overlay_animation_.reset(); |
104 if (active_overlay_) { | 124 if (active_overlay_) { |
| 125 overlay_view_->Detach(); |
| 126 overlay_view_ = NULL; |
105 active_overlay_->Close(); | 127 active_overlay_->Close(); |
106 active_overlay_ = NULL; | 128 active_overlay_ = NULL; |
107 } | 129 } |
108 } | 130 } |
109 | 131 |
110 void ContentsContainer::AnimationProgressed(const Animation* animation) { | 132 void ContentsContainer::AnimationProgressed(const Animation* animation) { |
111 active_overlay_->SetOpacity( | 133 active_overlay_->SetOpacity( |
112 Tween::ValueBetween(animation->GetCurrentValue(), kMinOpacity, | 134 Tween::ValueBetween(animation->GetCurrentValue(), kMinOpacity, |
113 kMaxOpacity)); | 135 kMaxOpacity)); |
114 active_overlay_->GetRootView()->SchedulePaint(); | 136 active_overlay_->GetRootView()->SchedulePaint(); |
115 } | 137 } |
116 | 138 |
117 void ContentsContainer::Layout() { | 139 void ContentsContainer::Layout() { |
118 // The active view always gets the full bounds. | 140 // The active view always gets the full bounds. |
119 active_->SetBounds(0, active_top_margin_, width(), | 141 active_->SetBounds(0, active_top_margin_, width(), |
120 std::max(0, height() - active_top_margin_)); | 142 std::max(0, height() - active_top_margin_)); |
121 | 143 |
122 if (preview_) | 144 if (preview_) |
123 preview_->SetBounds(0, 0, width(), height()); | 145 preview_->SetBounds(0, 0, width(), height()); |
124 | 146 |
125 // Need to invoke views::View in case any views whose bounds didn't change | 147 // Need to invoke views::View in case any views whose bounds didn't change |
126 // still need a layout. | 148 // still need a layout. |
127 views::View::Layout(); | 149 views::View::Layout(); |
128 } | 150 } |
| 151 |
| 152 void ContentsContainer::CreateOverlay(int initial_opacity) { |
| 153 DCHECK(!active_overlay_); |
| 154 active_overlay_ = views::Widget::CreatePopupWidget(views::Widget::Transparent, |
| 155 views::Widget::NotAcceptEvents, |
| 156 views::Widget::DeleteOnDestroy, |
| 157 views::Widget::MirrorOriginInRTL); |
| 158 active_overlay_->SetOpacity(initial_opacity); |
| 159 gfx::Point screen_origin; |
| 160 views::View::ConvertPointToScreen(active_, &screen_origin); |
| 161 gfx::Rect overlay_bounds(screen_origin, active_->size()); |
| 162 active_overlay_->Init(active_->GetWidget()->GetNativeView(), overlay_bounds); |
| 163 overlay_view_ = new OverlayContentView(this); |
| 164 overlay_view_->set_background( |
| 165 views::Background::CreateSolidBackground(SK_ColorWHITE)); |
| 166 active_overlay_->SetContentsView(overlay_view_); |
| 167 active_overlay_->Show(); |
| 168 active_overlay_->MoveAbove(active_->GetWidget()); |
| 169 } |
| 170 |
| 171 void ContentsContainer::OverlayViewDestroyed() { |
| 172 active_overlay_ = NULL; |
| 173 overlay_view_ = NULL; |
| 174 } |
OLD | NEW |