| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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/ui/views/frame/contents_container.h" | 5 #include "chrome/browser/ui/views/frame/contents_container.h" |
| 6 | 6 |
| 7 #include "grit/theme_resources.h" | 7 #include "grit/theme_resources.h" |
| 8 #include "ui/base/resource/resource_bundle.h" | 8 #include "ui/base/resource/resource_bundle.h" |
| 9 #include "ui/gfx/canvas.h" | 9 #include "ui/gfx/canvas.h" |
| 10 #include "ui/gfx/image/image_skia.h" | 10 #include "ui/gfx/image/image_skia.h" |
| 11 | 11 |
| 12 // static | 12 // static |
| 13 const char ContentsContainer::kViewClassName[] = | 13 const char ContentsContainer::kViewClassName[] = |
| 14 "browser/ui/views/frame/ContentsContainer"; | 14 "browser/ui/views/frame/ContentsContainer"; |
| 15 | 15 |
| 16 namespace { | 16 namespace { |
| 17 | 17 |
| 18 int PreviewHeightInPixels(int parent_height, int preview_height, | 18 int OverlayHeightInPixels(int parent_height, |
| 19 InstantSizeUnits preview_height_units) { | 19 int overlay_height, |
| 20 preview_height = std::max(0, preview_height); | 20 bool is_height_in_pixels) { |
| 21 switch (preview_height_units) { | 21 overlay_height = std::max(0, overlay_height); |
| 22 case INSTANT_SIZE_PERCENT: | 22 return std::min(parent_height, is_height_in_pixels ? |
| 23 return std::min(parent_height, (parent_height * preview_height) / 100); | 23 overlay_height : (parent_height * overlay_height) / 100); |
| 24 | |
| 25 case INSTANT_SIZE_PIXELS: | |
| 26 return std::min(parent_height, preview_height); | |
| 27 } | |
| 28 NOTREACHED() << "unknown units: " << preview_height_units; | |
| 29 return 0; | |
| 30 } | 24 } |
| 31 | 25 |
| 32 // This class draws the drop shadow below the preview when the non-NTP preview | 26 // This class draws the drop shadow below the overlay when the non-NTP overlay |
| 33 // doesn't fill up the entire content page. | 27 // doesn't fill up the entire content page. |
| 34 // This class is owned by ContentsContainer, which: | 28 // This class is owned by ContentsContainer, which: |
| 35 // - adds it as child when shadow is needed | 29 // - adds it as child when shadow is needed |
| 36 // - removes it as child when shadow is not needed or when preview is nuked or | 30 // - removes it as child when shadow is not needed or when overlay is nuked or |
| 37 // when preview is removed as child | 31 // when overlay is removed as child |
| 38 // - always makes sure it's the 3rd child in the view hierarchy i.e. after | 32 // - always makes sure it's the 3rd child in the view hierarchy i.e. after |
| 39 // active and preview. | 33 // active and overlay. |
| 40 class ShadowView : public views::View { | 34 class ShadowView : public views::View { |
| 41 public: | 35 public: |
| 42 ShadowView() { | 36 ShadowView() { |
| 43 drop_shadow_ = *ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | 37 drop_shadow_ = *ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
| 44 IDR_PREVIEW_DROP_SHADOW); | 38 IDR_OVERLAY_DROP_SHADOW); |
| 45 | 39 |
| 46 SetPaintToLayer(true); | 40 SetPaintToLayer(true); |
| 47 SetFillsBoundsOpaquely(false); | 41 SetFillsBoundsOpaquely(false); |
| 48 set_owned_by_client(); | 42 set_owned_by_client(); |
| 49 } | 43 } |
| 50 | 44 |
| 51 virtual ~ShadowView() {} | 45 virtual ~ShadowView() {} |
| 52 | 46 |
| 53 virtual gfx::Size GetPreferredSize() OVERRIDE { | 47 virtual gfx::Size GetPreferredSize() OVERRIDE { |
| 54 // Only height really matters, since images will be stretched horizontally | 48 // Only height really matters, since images will be stretched horizontally |
| (...skipping 14 matching lines...) Expand all Loading... |
| 69 private: | 63 private: |
| 70 gfx::ImageSkia drop_shadow_; | 64 gfx::ImageSkia drop_shadow_; |
| 71 | 65 |
| 72 DISALLOW_COPY_AND_ASSIGN(ShadowView); | 66 DISALLOW_COPY_AND_ASSIGN(ShadowView); |
| 73 }; | 67 }; |
| 74 | 68 |
| 75 } // namespace | 69 } // namespace |
| 76 | 70 |
| 77 ContentsContainer::ContentsContainer(views::WebView* active) | 71 ContentsContainer::ContentsContainer(views::WebView* active) |
| 78 : active_(active), | 72 : active_(active), |
| 79 preview_(NULL), | 73 overlay_(NULL), |
| 80 preview_web_contents_(NULL), | 74 overlay_web_contents_(NULL), |
| 81 draw_drop_shadow_(false), | 75 draw_drop_shadow_(false), |
| 82 active_top_margin_(0), | 76 active_top_margin_(0), |
| 83 preview_height_(100), | 77 overlay_height_(100), |
| 84 preview_height_units_(INSTANT_SIZE_PERCENT) { | 78 is_height_in_pixels_(false) { |
| 85 AddChildView(active_); | 79 AddChildView(active_); |
| 86 } | 80 } |
| 87 | 81 |
| 88 ContentsContainer::~ContentsContainer() { | 82 ContentsContainer::~ContentsContainer() { |
| 89 RemoveShadowView(true); | 83 RemoveShadowView(true); |
| 90 } | 84 } |
| 91 | 85 |
| 92 void ContentsContainer::MakePreviewContentsActiveContents() { | 86 void ContentsContainer::MakeOverlayContentsActiveContents() { |
| 93 DCHECK(preview_); | 87 DCHECK(overlay_); |
| 94 | 88 |
| 95 active_ = preview_; | 89 active_ = overlay_; |
| 96 preview_ = NULL; | 90 overlay_ = NULL; |
| 97 preview_web_contents_ = NULL; | 91 overlay_web_contents_ = NULL; |
| 98 // Since |preview_| has been nuked, shadow view is not needed anymore. | 92 // Since |overlay_| has been nuked, shadow view is not needed anymore. |
| 99 // Note that the previous |active_| will be deleted by caller (see | 93 // Note that the previous |active_| will be deleted by caller (see |
| 100 // BrowserView::ActiveTabChanged()) after this call, hence removing the old | 94 // BrowserView::ActiveTabChanged()) after this call, hence removing the old |
| 101 // |active_| as a child, and making the new |active_| (which is the previous | 95 // |active_| as a child, and making the new |active_| (which is the previous |
| 102 // |preview_|) the first child. | 96 // |overlay_|) the first child. |
| 103 RemoveShadowView(true); | 97 RemoveShadowView(true); |
| 104 Layout(); | 98 Layout(); |
| 105 } | 99 } |
| 106 | 100 |
| 107 void ContentsContainer::SetPreview(views::WebView* preview, | 101 void ContentsContainer::SetOverlay(views::WebView* overlay, |
| 108 content::WebContents* preview_web_contents, | 102 content::WebContents* overlay_web_contents, |
| 109 const chrome::search::Mode& search_mode, | |
| 110 int height, | 103 int height, |
| 111 InstantSizeUnits units, | 104 bool is_height_in_pixels, |
| 112 bool draw_drop_shadow) { | 105 bool draw_drop_shadow) { |
| 113 // If drawing drop shadow, clip the bottom 1-px-thick separator out of | 106 // If drawing drop shadow, clip the bottom 1-px-thick separator out of |
| 114 // preview. | 107 // overlay. |
| 115 // TODO(kuan): remove this when GWS gives chrome the height without the | 108 // TODO(kuan): remove this when GWS gives chrome the height without the |
| 116 // separator. | 109 // separator. |
| 117 #if !defined(OS_WIN) | 110 #if !defined(OS_WIN) |
| 118 if (draw_drop_shadow) | 111 if (draw_drop_shadow) |
| 119 --height; | 112 --height; |
| 120 #endif // !defined(OS_WIN) | 113 #endif // !defined(OS_WIN) |
| 121 | 114 |
| 122 if (preview_ == preview && preview_web_contents_ == preview_web_contents && | 115 if (overlay_ == overlay && overlay_web_contents_ == overlay_web_contents && |
| 123 search_mode_ == search_mode && preview_height_ == height && | 116 overlay_height_ == height && |
| 124 preview_height_units_ == units && draw_drop_shadow_ == draw_drop_shadow) { | 117 is_height_in_pixels_ == is_height_in_pixels && |
| 118 draw_drop_shadow_ == draw_drop_shadow) |
| 125 return; | 119 return; |
| 120 |
| 121 if (overlay_ != overlay) { |
| 122 if (overlay_) { |
| 123 // Order of children is important: always |active_| first, then |
| 124 // |overlay_|, then shadow view if necessary. To make sure the next view |
| 125 // is added in the right order, remove shadow view every time |overlay_| |
| 126 // is removed. |
| 127 RemoveShadowView(false); |
| 128 RemoveChildView(overlay_); |
| 129 } |
| 130 overlay_ = overlay; |
| 131 if (overlay_) |
| 132 AddChildView(overlay_); |
| 126 } | 133 } |
| 127 | 134 |
| 128 if (preview_ != preview) { | 135 overlay_web_contents_ = overlay_web_contents; |
| 129 if (preview_) { | 136 overlay_height_ = height; |
| 130 // Order of children is important: always |active_| first, then | 137 is_height_in_pixels_ = is_height_in_pixels; |
| 131 // |preview_|, then shadow view if necessary. To make sure the next view | |
| 132 // is added in the right order, remove shadow view every time |preview_| | |
| 133 // is removed. | |
| 134 RemoveShadowView(false); | |
| 135 RemoveChildView(preview_); | |
| 136 } | |
| 137 preview_ = preview; | |
| 138 if (preview_) | |
| 139 AddChildView(preview_); | |
| 140 } | |
| 141 | |
| 142 preview_web_contents_ = preview_web_contents; | |
| 143 search_mode_ = search_mode; | |
| 144 preview_height_ = height; | |
| 145 preview_height_units_ = units; | |
| 146 draw_drop_shadow_ = draw_drop_shadow; | 138 draw_drop_shadow_ = draw_drop_shadow; |
| 147 | 139 |
| 148 // Add shadow view if there's preview and drop shadow is needed. | 140 // Add shadow view if there's overlay and drop shadow is needed. |
| 149 // Remove shadow view if there's no preview. | 141 // Remove shadow view if there's no overlay. |
| 150 // If there's preview and drop shadow is not needed, that means the partial- | 142 // If there's overlay and drop shadow is not needed, that means the partial- |
| 151 // height preview is going to be full-height. Don't remove the shadow view | 143 // height overlay is going to be full-height. Don't remove the shadow view |
| 152 // yet because its layered view will disappear before the non-layered preview | 144 // yet because its layered view will disappear before the non-layered overlay |
| 153 // is repainted at the full height, leaving no separator between the preview | 145 // is repainted at the full height, leaving no separator between the overlay |
| 154 // and active contents. When the preview is repainted at the full height, the | 146 // and active contents. When the overlay is repainted at the full height, the |
| 155 // shadow view, which remains at the original position below the partial- | 147 // shadow view, which remains at the original position below the partial- |
| 156 // height preview, will automatically be obscured the full-height preview. | 148 // height overlay, will automatically be obscured by the full-height overlay. |
| 157 if (preview_ && draw_drop_shadow_) { | 149 if (overlay_ && draw_drop_shadow_) { |
| 158 #if !defined(OS_WIN) | 150 #if !defined(OS_WIN) |
| 159 if (!shadow_view_.get()) // Shadow view has not been created. | 151 if (!shadow_view_.get()) // Shadow view has not been created. |
| 160 shadow_view_.reset(new ShadowView()); | 152 shadow_view_.reset(new ShadowView()); |
| 161 if (!shadow_view_->parent()) // Shadow view has not been added. | 153 if (!shadow_view_->parent()) // Shadow view has not been added. |
| 162 AddChildView(shadow_view_.get()); | 154 AddChildView(shadow_view_.get()); |
| 163 #endif // !defined(OS_WIN) | 155 #endif // !defined(OS_WIN) |
| 164 } else if (!preview_) { | 156 } else if (!overlay_) { |
| 165 RemoveShadowView(true); | 157 RemoveShadowView(true); |
| 166 } | 158 } |
| 167 | 159 |
| 168 Layout(); | 160 Layout(); |
| 169 } | 161 } |
| 170 | 162 |
| 171 void ContentsContainer::MaybeStackPreviewAtTop() { | |
| 172 if (!preview_) | |
| 173 return; | |
| 174 // To force |preview_| to the topmost in the z-order, remove it, then add it | |
| 175 // back. | |
| 176 // See comments in SetPreview() for why shadow view is removed. | |
| 177 bool removed_shadow = RemoveShadowView(false); | |
| 178 RemoveChildView(preview_); | |
| 179 AddChildView(preview_); | |
| 180 if (removed_shadow) // Add back shadow view if it was removed. | |
| 181 AddChildView(shadow_view_.get()); | |
| 182 Layout(); | |
| 183 } | |
| 184 | |
| 185 void ContentsContainer::SetActiveTopMargin(int margin) { | 163 void ContentsContainer::SetActiveTopMargin(int margin) { |
| 186 if (active_top_margin_ == margin) | 164 if (active_top_margin_ == margin) |
| 187 return; | 165 return; |
| 188 | 166 |
| 189 active_top_margin_ = margin; | 167 active_top_margin_ = margin; |
| 190 // Make sure we layout next time around. We need this in case our bounds | 168 // Make sure we layout next time around. We need this in case our bounds |
| 191 // haven't changed. | 169 // haven't changed. |
| 192 InvalidateLayout(); | 170 InvalidateLayout(); |
| 193 } | 171 } |
| 194 | 172 |
| 195 gfx::Rect ContentsContainer::GetPreviewBounds() const { | 173 gfx::Rect ContentsContainer::GetOverlayBounds() const { |
| 196 gfx::Point screen_loc; | 174 gfx::Point screen_loc; |
| 197 ConvertPointToScreen(this, &screen_loc); | 175 ConvertPointToScreen(this, &screen_loc); |
| 198 return gfx::Rect(screen_loc, size()); | 176 return gfx::Rect(screen_loc, size()); |
| 199 } | 177 } |
| 200 | 178 |
| 201 bool ContentsContainer::IsPreviewFullHeight( | 179 bool ContentsContainer::IsOverlayFullHeight(int overlay_height, |
| 202 int preview_height, | 180 bool is_height_in_pixels) const { |
| 203 InstantSizeUnits preview_height_units) const { | 181 int height_in_pixels = OverlayHeightInPixels(height(), overlay_height, |
| 204 int height_in_pixels = PreviewHeightInPixels(height(), preview_height, | 182 is_height_in_pixels); |
| 205 preview_height_units); | |
| 206 return height_in_pixels == height(); | 183 return height_in_pixels == height(); |
| 207 } | 184 } |
| 208 | 185 |
| 209 void ContentsContainer::Layout() { | 186 void ContentsContainer::Layout() { |
| 210 int content_y = active_top_margin_; | 187 int content_y = active_top_margin_; |
| 211 int content_height = std::max(0, height() - content_y); | 188 int content_height = std::max(0, height() - content_y); |
| 212 | 189 |
| 213 active_->SetBounds(0, content_y, width(), content_height); | 190 active_->SetBounds(0, content_y, width(), content_height); |
| 214 | 191 |
| 215 if (preview_) { | 192 if (overlay_) { |
| 216 preview_->SetBounds(0, 0, width(), | 193 overlay_->SetBounds(0, 0, width(), |
| 217 PreviewHeightInPixels(height(), preview_height_, | 194 OverlayHeightInPixels(height(), overlay_height_, |
| 218 preview_height_units_)); | 195 is_height_in_pixels_)); |
| 219 if (draw_drop_shadow_) { | 196 if (draw_drop_shadow_) { |
| 220 #if !defined(OS_WIN) | 197 #if !defined(OS_WIN) |
| 221 DCHECK(shadow_view_.get() && shadow_view_->parent()); | 198 DCHECK(shadow_view_.get() && shadow_view_->parent()); |
| 222 shadow_view_->SetBounds(0, preview_->bounds().height(), width(), | 199 shadow_view_->SetBounds(0, overlay_->bounds().height(), width(), |
| 223 shadow_view_->GetPreferredSize().height()); | 200 shadow_view_->GetPreferredSize().height()); |
| 224 #endif // !defined(OS_WIN) | 201 #endif // !defined(OS_WIN) |
| 225 } | 202 } |
| 226 } | 203 } |
| 227 | 204 |
| 228 // Need to invoke views::View in case any views whose bounds didn't change | 205 // Need to invoke views::View in case any views whose bounds didn't change |
| 229 // still need a layout. | 206 // still need a layout. |
| 230 views::View::Layout(); | 207 views::View::Layout(); |
| 231 } | 208 } |
| 232 | 209 |
| 233 bool ContentsContainer::RemoveShadowView(bool delete_view) { | 210 bool ContentsContainer::RemoveShadowView(bool delete_view) { |
| 234 if (!shadow_view_.get()) | 211 if (!shadow_view_.get()) |
| 235 return false; | 212 return false; |
| 236 | 213 |
| 237 if (!shadow_view_->parent()) { | 214 if (!shadow_view_->parent()) { |
| 238 if (delete_view) | 215 if (delete_view) |
| 239 shadow_view_.reset(NULL); | 216 shadow_view_.reset(NULL); |
| 240 return false; | 217 return false; |
| 241 } | 218 } |
| 242 | 219 |
| 243 RemoveChildView(shadow_view_.get()); | 220 RemoveChildView(shadow_view_.get()); |
| 244 if (delete_view) | 221 if (delete_view) |
| 245 shadow_view_.reset(NULL); | 222 shadow_view_.reset(NULL); |
| 246 return true; | 223 return true; |
| 247 } | 224 } |
| 248 | 225 |
| 249 std::string ContentsContainer::GetClassName() const { | 226 std::string ContentsContainer::GetClassName() const { |
| 250 return kViewClassName; | 227 return kViewClassName; |
| 251 } | 228 } |
| OLD | NEW |