| Index: chrome/browser/views/frame/contents_container.cc
|
| diff --git a/chrome/browser/views/frame/contents_container.cc b/chrome/browser/views/frame/contents_container.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3d455eff3b0fadaf9e124cb9cdbe249c9a2c4495
|
| --- /dev/null
|
| +++ b/chrome/browser/views/frame/contents_container.cc
|
| @@ -0,0 +1,194 @@
|
| +// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/views/frame/contents_container.h"
|
| +
|
| +#include "app/resource_bundle.h"
|
| +#include "chrome/browser/location_bar.h"
|
| +#include "chrome/browser/views/frame/browser_view.h"
|
| +#include "grit/theme_resources.h"
|
| +#include "views/controls/image_view.h"
|
| +#include "views/widget/root_view.h"
|
| +
|
| +#if defined(OS_WIN)
|
| +#include "views/widget/widget_win.h"
|
| +#elif defined(OS_LINUX)
|
| +#include "chrome/browser/gtk/gtk_util.h"
|
| +#include "views/window/window_gtk.h"
|
| +#endif
|
| +
|
| +#if defined(OS_WIN)
|
| +
|
| +class ContentsContainer::TearWindow : public views::WidgetWin {
|
| + public:
|
| + explicit TearWindow(ContentsContainer* contents_container)
|
| + : contents_container_(contents_container) {
|
| + set_window_style(WS_POPUP | WS_CLIPCHILDREN);
|
| + set_window_ex_style(WS_EX_TOOLWINDOW | WS_EX_LAYERED);
|
| + }
|
| +
|
| + virtual ~TearWindow() {
|
| + // On windows it's possible for us to be deleted before the
|
| + // ContentsContainer. If this happens make sure contents_container_ doesn't
|
| + // attempt to delete us too.
|
| + if (contents_container_)
|
| + contents_container_->TearWindowDestroyed();
|
| + }
|
| +
|
| + void set_contents_container(ContentsContainer* contents_container) {
|
| + contents_container_ = contents_container;
|
| + }
|
| +
|
| + virtual LRESULT OnMouseActivate(HWND window,
|
| + UINT hit_test,
|
| + UINT mouse_message) {
|
| + // Don't activate the window when the user clicks it.
|
| + contents_container_->browser_view_->GetLocationBar()->Revert();
|
| + return MA_NOACTIVATE;
|
| + }
|
| +
|
| + private:
|
| + ContentsContainer* contents_container_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TearWindow);
|
| +};
|
| +
|
| +#endif
|
| +
|
| +ContentsContainer::ContentsContainer(BrowserView* browser_view,
|
| + views::View* active)
|
| + : browser_view_(browser_view),
|
| + active_(active),
|
| + preview_(NULL),
|
| + preview_tab_contents_(NULL),
|
| + tear_window_(NULL),
|
| + active_top_margin_(0) {
|
| + AddChildView(active_);
|
| +}
|
| +
|
| +ContentsContainer::~ContentsContainer() {
|
| + DeleteTearWindow();
|
| +}
|
| +
|
| +void ContentsContainer::MakePreviewContentsActiveContents() {
|
| + active_ = preview_;
|
| + preview_ = NULL;
|
| + DeleteTearWindow();
|
| + Layout();
|
| +}
|
| +
|
| +void ContentsContainer::SetPreview(views::View* preview,
|
| + TabContents* preview_tab_contents) {
|
| + if (preview == preview_)
|
| + return;
|
| +
|
| + if (preview_) {
|
| + RemoveChildView(preview_);
|
| + DeleteTearWindow();
|
| + }
|
| + preview_ = preview;
|
| + preview_tab_contents_ = preview_tab_contents;
|
| + if (preview_) {
|
| + AddChildView(preview_);
|
| + CreateTearWindow();
|
| + }
|
| +
|
| + Layout();
|
| +
|
| + if (preview_)
|
| + tear_window_->Show(); // Show after we'ved positioned it in Layout.
|
| +}
|
| +
|
| +void ContentsContainer::SetActiveTopMargin(int margin) {
|
| + if (active_top_margin_ == margin)
|
| + return;
|
| +
|
| + active_top_margin_ = margin;
|
| + // Make sure we layout next time around. We need this in case our bounds
|
| + // haven't changed.
|
| + InvalidateLayout();
|
| +}
|
| +
|
| +void ContentsContainer::Layout() {
|
| + // The active view always gets the full bounds.
|
| + active_->SetBounds(0, active_top_margin_, width(),
|
| + std::max(0, height() - active_top_margin_));
|
| +
|
| + if (preview_) {
|
| + preview_->SetBounds(0, 0, width(), height());
|
| + PositionTearWindow();
|
| + }
|
| +
|
| + // Need to invoke views::View in case any views whose bounds didn't change
|
| + // still need a layout.
|
| + views::View::Layout();
|
| +}
|
| +
|
| +void ContentsContainer::CreateTearWindow() {
|
| + DCHECK(preview_);
|
| + tear_window_ = CreateTearWindowImpl();
|
| +
|
| + views::ImageView* image_view = new views::ImageView();
|
| + image_view->SetImage(ResourceBundle::GetSharedInstance().GetBitmapNamed(
|
| + IDR_MATCH_PREVIEW_TEAR));
|
| + tear_window_->SetContentsView(image_view);
|
| +}
|
| +
|
| +#if defined(OS_WIN)
|
| +
|
| +ContentsContainer::TearWindow* ContentsContainer::CreateTearWindowImpl() {
|
| + TearWindow* widget = new TearWindow(this);
|
| + widget->Init(browser_view_->GetNativeHandle(), gfx::Rect());
|
| + return widget;
|
| +}
|
| +
|
| +#elif defined(OS_LINUX)
|
| +
|
| +ContentsContainer::TearWindow* ContentsContainer::CreateTearWindowImpl() {
|
| + views::WidgetGtk* widget = new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP);
|
| + widget->MakeTransparent();
|
| + widget->Init(NULL, gfx::Rect());
|
| + gtk_util::StackPopupWindow(widget->GetNativeView(),
|
| + GTK_WIDGET(browser_view_->GetNativeHandle()));
|
| + return widget;
|
| +}
|
| +
|
| +#endif
|
| +
|
| +void ContentsContainer::PositionTearWindow() {
|
| + if (!tear_window_)
|
| + return;
|
| +
|
| + gfx::Rect vis_bounds = GetVisibleBounds();
|
| +
|
| + gfx::Size pref = tear_window_->GetRootView()->GetPreferredSize();
|
| + // Constrain to the the visible bounds as we may be given a different size
|
| + // than is actually visible.
|
| + pref.SetSize(std::min(pref.width(), vis_bounds.width()),
|
| + std::min(pref.height(), vis_bounds.height()));
|
| +
|
| + gfx::Rect bounds(0, 0, pref.width(), pref.height());
|
| + bounds.set_x(MirroredLeftPointForRect(bounds));
|
| +
|
| + gfx::Point origin(bounds.origin());
|
| + views::View::ConvertPointToScreen(this, &origin);
|
| +
|
| + tear_window_->SetBounds(gfx::Rect(origin, pref));
|
| +}
|
| +
|
| +void ContentsContainer::DeleteTearWindow() {
|
| + if (!tear_window_)
|
| + return;
|
| +
|
| + tear_window_->Close();
|
| +#if defined(OS_WIN)
|
| + tear_window_->set_contents_container(NULL);
|
| +#endif
|
| + // Close deletes the tear window.
|
| + tear_window_ = NULL;
|
| +}
|
| +
|
| +void ContentsContainer::TearWindowDestroyed() {
|
| + tear_window_ = NULL;
|
| +}
|
|
|