| Index: chrome/browser/ui/views/panels/panel_stack_view.cc
|
| diff --git a/chrome/browser/ui/views/panels/panel_stack_view.cc b/chrome/browser/ui/views/panels/panel_stack_view.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..0f98ead8974c9ca0bb278b88c5c9a87cccbfe256
|
| --- /dev/null
|
| +++ b/chrome/browser/ui/views/panels/panel_stack_view.cc
|
| @@ -0,0 +1,159 @@
|
| +// Copyright (c) 2013 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/ui/views/panels/panel_stack_view.h"
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/utf_string_conversions.h"
|
| +#include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/browser/ui/panels/panel.h"
|
| +#include "chrome/browser/ui/panels/stacked_panel_collection.h"
|
| +#include "chrome/common/extensions/extension.h"
|
| +#include "ui/gfx/rect.h"
|
| +#include "ui/views/widget/widget.h"
|
| +
|
| +#if defined(OS_WIN)
|
| +#include "chrome/browser/shell_integration.h"
|
| +#include "ui/base/win/shell.h"
|
| +#endif
|
| +
|
| +// static
|
| +NativePanelStack* NativePanelStack::Create(
|
| + scoped_ptr<StackedPanelCollection> stacked_collection) {
|
| +#if defined(OS_WIN)
|
| + return new PanelStackView(stacked_collection.Pass());
|
| +#else
|
| + NOTIMPLEMENTED();
|
| + return NULL;
|
| +#endif
|
| +}
|
| +
|
| +PanelStackView::PanelStackView(
|
| + scoped_ptr<StackedPanelCollection> stacked_collection)
|
| + : stacked_collection_(stacked_collection.Pass()),
|
| + delay_initialized_(false),
|
| + window_(NULL) {
|
| + window_ = new views::Widget;
|
| + views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
|
| + params.delegate = this;
|
| + params.remove_standard_frame = true;
|
| + params.transparent = true;
|
| + // Empty size is not allowed so a temporary small size is passed. SetBounds
|
| + // will be called later to update the bounds.
|
| + params.bounds = gfx::Rect(0, 0, 1, 1);
|
| + window_->Init(params);
|
| + window_->set_frame_type(views::Widget::FRAME_TYPE_FORCE_CUSTOM);
|
| + window_->set_focus_on_creation(false);
|
| + window_->AddObserver(this);
|
| + window_->ShowInactive();
|
| +}
|
| +
|
| +PanelStackView::~PanelStackView() {
|
| +}
|
| +
|
| +void PanelStackView::EnsureInitialized() {
|
| + // The stack view cannot be fully initialized until the first panel has been
|
| + // added to the stack because we need the information from that panel.
|
| + if (delay_initialized_)
|
| + return;
|
| + Panel* panel = stacked_collection_->top_panel();
|
| + if (!panel)
|
| + return;
|
| + delay_initialized_ = true;
|
| +
|
| +#if defined(OS_WIN) && !defined(USE_AURA)
|
| + ui::win::SetAppIdForWindow(
|
| + ShellIntegration::GetAppModelIdForProfile(UTF8ToWide(panel->app_name()),
|
| + panel->profile()->GetPath()),
|
| + window_->GetNativeWindow());
|
| +#endif
|
| +}
|
| +
|
| +void PanelStackView::Close() {
|
| + window_->Close();
|
| +}
|
| +
|
| +void PanelStackView::OnPanelAddedOrRemoved(Panel* panel) {
|
| + EnsureInitialized();
|
| +
|
| + UpdateWindowOwnerForTaskbarIconAppearance(panel);
|
| +
|
| + window_->UpdateWindowTitle();
|
| + window_->UpdateWindowIcon();
|
| +}
|
| +
|
| +void PanelStackView::SetBounds(const gfx::Rect& bounds) {
|
| + window_->SetBounds(bounds);
|
| +}
|
| +
|
| +string16 PanelStackView::GetWindowTitle() const {
|
| + Panel* panel = stacked_collection_->top_panel();
|
| + if (!panel)
|
| + return string16();
|
| +
|
| + const extensions::Extension* extension = panel->GetExtension();
|
| + return UTF8ToUTF16(extension && !extension->name().empty() ?
|
| + extension->name() : panel->app_name());
|
| +}
|
| +
|
| +gfx::ImageSkia PanelStackView::GetWindowAppIcon() {
|
| + Panel* panel = stacked_collection_->top_panel();
|
| + if (panel) {
|
| + gfx::Image app_icon = panel->app_icon();
|
| + if (!app_icon.IsEmpty())
|
| + return *app_icon.ToImageSkia();
|
| + }
|
| + return gfx::ImageSkia();
|
| +}
|
| +
|
| +gfx::ImageSkia PanelStackView::GetWindowIcon() {
|
| + return GetWindowAppIcon();
|
| +}
|
| +
|
| +views::Widget* PanelStackView::GetWidget() {
|
| + return window_;
|
| +}
|
| +
|
| +const views::Widget* PanelStackView::GetWidget() const {
|
| + return window_;
|
| +}
|
| +
|
| +void PanelStackView::DeleteDelegate() {
|
| + delete this;
|
| +}
|
| +
|
| +void PanelStackView::OnWidgetClosing(views::Widget* widget) {
|
| + window_ = NULL;
|
| +}
|
| +
|
| +void PanelStackView::UpdateWindowOwnerForTaskbarIconAppearance(Panel* panel) {
|
| +#if defined(OS_WIN) && !defined(USE_AURA)
|
| + HWND panel_window = panel->GetNativeWindow();
|
| +
|
| + HWND stack_window = NULL;
|
| + StackedPanelCollection* stack = panel->stack();
|
| + if (stack) {
|
| + stack_window = static_cast<PanelStackView*>(stack->native_stack())->
|
| + window_->GetNativeWindow();
|
| + }
|
| +
|
| + // The extended style WS_EX_APPWINDOW is used to force a top-level window onto
|
| + // the taskbar. In order for multiple stacked panels to appear as one, this
|
| + // bit needs to be cleared.
|
| + int value = ::GetWindowLong(panel_window, GWL_EXSTYLE);
|
| + ::SetWindowLong(
|
| + panel_window,
|
| + GWL_EXSTYLE,
|
| + stack_window ? (value & ~WS_EX_APPWINDOW) : (value | WS_EX_APPWINDOW));
|
| +
|
| + // All the windows that share the same owner window will appear as a single
|
| + // window on the taskbar.
|
| + ::SetWindowLong(panel_window,
|
| + GWL_HWNDPARENT,
|
| + reinterpret_cast<LONG>(stack_window));
|
| +
|
| +#else
|
| + NOTIMPLEMENTED();
|
| +#endif
|
| +}
|
|
|