Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012 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/panels/panel_stack_view.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "base/utf_string_conversions.h" | |
| 9 #include "chrome/browser/profiles/profile.h" | |
| 10 #include "chrome/browser/ui/panels/panel.h" | |
| 11 #include "chrome/browser/ui/panels/stacked_panel_collection.h" | |
| 12 #include "chrome/common/extensions/extension.h" | |
| 13 #include "ui/gfx/rect.h" | |
| 14 #include "ui/views/widget/widget.h" | |
| 15 | |
| 16 #if defined(OS_WIN) | |
| 17 #include "chrome/browser/shell_integration.h" | |
| 18 #include "ui/base/win/shell.h" | |
| 19 #endif | |
| 20 | |
| 21 // static | |
| 22 NativePanelStack* NativePanelStack::Create( | |
| 23 scoped_ptr<StackedPanelCollection> stacked_collection) { | |
| 24 #if defined(OS_WIN) | |
| 25 return new PanelStackView(stacked_collection.Pass()); | |
| 26 #else | |
| 27 NOTIMPLEMENTED(); | |
| 28 return NULL; | |
| 29 #endif | |
| 30 } | |
| 31 | |
| 32 PanelStackView::PanelStackView( | |
| 33 scoped_ptr<StackedPanelCollection> stacked_collection) | |
| 34 : stacked_collection_(stacked_collection.Pass()), | |
| 35 delay_initialized_(false), | |
| 36 window_(NULL) { | |
| 37 window_ = new views::Widget; | |
| 38 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | |
| 39 params.delegate = this; | |
| 40 params.remove_standard_frame = true; | |
| 41 params.transparent = true; | |
| 42 // Empty size is not allowed so a temporary small size is passed. SetBounds | |
| 43 // will be called later to update the bounds. | |
| 44 params.bounds = gfx::Rect(0, 0, 1, 1); | |
| 45 window_->Init(params); | |
| 46 window_->set_frame_type(views::Widget::FRAME_TYPE_FORCE_CUSTOM); | |
| 47 window_->set_focus_on_creation(false); | |
| 48 window_->AddObserver(this); | |
| 49 window_->ShowInactive(); | |
| 50 } | |
| 51 | |
| 52 PanelStackView::~PanelStackView() { | |
| 53 } | |
| 54 | |
| 55 void PanelStackView::EnsureInitialized() { | |
| 56 // The stack view cannot be fully initialized until the first panel has been | |
| 57 // added to the stack because we need the information from that panel. | |
| 58 if (delay_initialized_) | |
| 59 return; | |
| 60 Panel* panel = stacked_collection_->top_panel(); | |
| 61 if (!panel) | |
| 62 return; | |
| 63 delay_initialized_ = true; | |
| 64 | |
| 65 #if defined(OS_WIN) && !defined(USE_AURA) | |
|
Dmitry Titov
2013/01/14 23:28:40
I think USE_AURA is only different that we should
jianli
2013/01/15 01:43:43
I will do it in a separate patch since there might
| |
| 66 ui::win::SetAppIdForWindow( | |
| 67 ShellIntegration::GetAppModelIdForProfile(UTF8ToWide(panel->app_name()), | |
| 68 panel->profile()->GetPath()), | |
| 69 window_->GetNativeWindow()); | |
| 70 #endif | |
| 71 } | |
| 72 | |
| 73 void PanelStackView::Close() { | |
| 74 window_->Close(); | |
| 75 } | |
| 76 | |
| 77 void PanelStackView::OnPanelAddedOrRemoved(Panel* panel) { | |
| 78 EnsureInitialized(); | |
| 79 | |
| 80 UpdateWindowOwnerForTaskbarIconAppearance(panel); | |
| 81 | |
| 82 window_->UpdateWindowTitle(); | |
| 83 window_->UpdateWindowIcon(); | |
| 84 } | |
| 85 | |
| 86 void PanelStackView::SetBounds(const gfx::Rect& bounds) { | |
| 87 window_->SetBounds(bounds); | |
| 88 } | |
| 89 | |
| 90 string16 PanelStackView::GetWindowTitle() const { | |
| 91 Panel* panel = stacked_collection_->top_panel(); | |
| 92 if (!panel) | |
| 93 return string16(); | |
| 94 | |
| 95 const extensions::Extension* extension = panel->GetExtension(); | |
| 96 return UTF8ToUTF16(extension && !extension->name().empty() ? | |
| 97 extension->name() : panel->app_name()); | |
| 98 } | |
| 99 | |
| 100 gfx::ImageSkia PanelStackView::GetWindowAppIcon() { | |
| 101 Panel* panel = stacked_collection_->top_panel(); | |
| 102 if (panel) { | |
| 103 gfx::Image app_icon = panel->app_icon(); | |
| 104 if (!app_icon.IsEmpty()) | |
| 105 return *app_icon.ToImageSkia(); | |
| 106 } | |
| 107 return gfx::ImageSkia(); | |
| 108 } | |
| 109 | |
| 110 gfx::ImageSkia PanelStackView::GetWindowIcon() { | |
| 111 return GetWindowAppIcon(); | |
| 112 } | |
| 113 | |
| 114 views::Widget* PanelStackView::GetWidget() { | |
| 115 return window_; | |
| 116 } | |
| 117 | |
| 118 const views::Widget* PanelStackView::GetWidget() const { | |
| 119 return window_; | |
| 120 } | |
| 121 | |
| 122 void PanelStackView::DeleteDelegate() { | |
| 123 delete this; | |
| 124 } | |
| 125 | |
| 126 void PanelStackView::OnWidgetClosing(views::Widget* widget) { | |
| 127 window_ = NULL; | |
| 128 } | |
| 129 | |
| 130 void PanelStackView::UpdateWindowOwnerForTaskbarIconAppearance(Panel* panel) { | |
| 131 #if defined(OS_WIN) && !defined(USE_AURA) | |
| 132 HWND panel_window = panel->GetNativeWindow(); | |
| 133 | |
| 134 HWND stack_window = NULL; | |
| 135 StackedPanelCollection* stack = panel->stack(); | |
| 136 if (stack) { | |
| 137 stack_window = static_cast<PanelStackView*>(stack->native_stack())-> | |
| 138 window_->GetNativeWindow(); | |
| 139 } | |
| 140 | |
| 141 // The extended style WS_EX_APPWINDOW is used to force a top-level window onto | |
| 142 // the taskbar. In order for multiple stacked panels to appear as one, this | |
| 143 // bit needs to be cleared. | |
| 144 int value = ::GetWindowLong(panel_window, GWL_EXSTYLE); | |
| 145 ::SetWindowLong( | |
| 146 panel_window, | |
| 147 GWL_EXSTYLE, | |
| 148 stack_window ? (value & ~WS_EX_APPWINDOW) : (value | WS_EX_APPWINDOW)); | |
| 149 | |
| 150 // All the windows that share the same owner window will appear as a single | |
| 151 // window on the taskbar. | |
| 152 ::SetWindowLong(panel_window, | |
| 153 GWL_HWNDPARENT, | |
| 154 reinterpret_cast<LONG>(stack_window)); | |
| 155 | |
| 156 #else | |
| 157 NOTIMPLEMENTED(); | |
| 158 #endif | |
| 159 } | |
| OLD | NEW |