Chromium Code Reviews| Index: chrome/browser/ui/views/aura/app_list_window.cc |
| diff --git a/chrome/browser/ui/views/aura/app_list_window.cc b/chrome/browser/ui/views/aura/app_list_window.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..2b134c5177145cf41ac758fcb7b83f82673e32aa |
| --- /dev/null |
| +++ b/chrome/browser/ui/views/aura/app_list_window.cc |
| @@ -0,0 +1,162 @@ |
| +// Copyright (c) 2011 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/aura/app_list_window.h" |
| + |
| +#include "chrome/browser/profiles/profile_manager.h" |
| +#include "chrome/browser/ui/views/dom_view.h" |
| +#include "content/browser/renderer_host/render_view_host.h" |
| +#include "content/browser/renderer_host/render_widget_host_view.h" |
| +#include "views/widget/widget.h" |
| +#include "ui/aura/desktop.h" |
| +#include "ui/base/animation/slide_animation.h" |
| + |
| +namespace { |
| + |
| +// The duration of the animation in milliseconds. |
| +const int kAnimationDurationMS = 200; |
| + |
| +// The y-axis offset used at the beginning of showing animation. |
| +const int kMoveUpAnimationOffset = 50; |
| + |
| +// Gets preferred position and size of app list window. |
| +gfx::Rect GetPreferredPosition() { |
| + aura::Desktop* desktop_window = aura::Desktop::GetInstance(); |
|
sky
2011/10/25 17:59:27
Go through screen instead of this. That way you ca
xiyuan
2011/10/27 22:51:29
Done.
|
| + gfx::Rect widget_bounds(desktop_window->bounds()); |
| + widget_bounds.Inset(150, 100); |
| + |
| + return widget_bounds; |
| +} |
| + |
| +} |
|
sky
2011/10/25 17:59:27
nit: // namespace
xiyuan
2011/10/27 22:51:29
Done.
|
| + |
| +// static |
| +AppListWindow* AppListWindow::instance_ = NULL; |
| + |
| +AppListWindow::AppListWindow() |
| + : widget_(NULL), |
| + contents_(NULL) { |
| +} |
| + |
| +AppListWindow::~AppListWindow() { |
| +} |
| + |
| +void AppListWindow::DeleteDelegate() { |
| + delete this; |
| +} |
| + |
| +views::View* AppListWindow::GetContentsView() { |
| + return contents_; |
| +} |
| + |
| +void AppListWindow::WindowClosing() { |
| + aura::Desktop::GetInstance()->RemoveObserver(this); |
| + widget_ = NULL; |
| + instance_ = NULL; |
| +} |
| + |
| +views::Widget* AppListWindow::GetWidget() { |
| + return widget_; |
| +} |
| + |
| +const views::Widget* AppListWindow::GetWidget() const { |
| + return widget_; |
| +} |
| + |
| +void AppListWindow::AnimationEnded(const ui::Animation* animation) { |
| + if (animation_->GetCurrentValue() == 0) |
| + widget_->Hide(); |
| +} |
| + |
| +void AppListWindow::AnimationProgressed(const ui::Animation* animation) { |
| + SetAnimationProgress(animation_->GetCurrentValue()); |
| +} |
| + |
| +void AppListWindow::OnActiveWindowChanged(aura::Window* active) { |
| + if (widget_ && !widget_->IsActive() && IsShowing()) |
| + Show(false /* show */, true /* animate */); |
| +} |
| + |
| +void AppListWindow::Init() { |
| + DCHECK(!widget_ && !contents_); |
| + |
| + contents_ = new DOMView(); |
| + contents_->Init(ProfileManager::GetDefaultProfile(), NULL); |
| + contents_->LoadURL(GURL("chrome://newtab#applist")); |
| + |
| + // Use a background with transparency to trigger transparent webkit. |
| + SkBitmap background; |
| + background.setConfig(SkBitmap::kARGB_8888_Config, 1, 1); |
| + background.allocPixels(); |
| + background.eraseARGB(0x00, 0x00, 0x00, 0x00); |
| + |
| + TabContents* tab = contents_->dom_contents()->tab_contents(); |
| + RenderViewHost* host = tab->render_view_host(); |
| + host->view()->SetBackground(background); |
| + |
| + views::Widget::InitParams widget_params( |
| + views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); |
| + widget_params.delegate = this; |
| + |
| + widget_ = new views::Widget; |
|
sky
2011/10/25 17:59:27
Users might go a long time before using the app li
xiyuan
2011/10/27 22:51:29
Done. Closes the window instead of hiding now.
|
| + widget_->Init(widget_params); |
| + widget_->SetContentsView(contents_); |
| + |
| + aura::Desktop::GetInstance()->AddObserver(this); |
| +} |
| + |
| +void AppListWindow::Show(bool show, bool animated) { |
| + if (animated) { |
| + if (!animation_.get()) { |
| + animation_.reset(new ui::SlideAnimation(this)); |
|
sky
2011/10/25 17:59:27
You should be able to accomplish both of these by
xiyuan
2011/10/27 22:51:29
Sort of done. Added a TODO to properly close windo
|
| + animation_->SetSlideDuration(kAnimationDurationMS); |
| + animation_->Reset(show ? 0.0 : 1.0); |
| + SetAnimationProgress(animation_->GetCurrentValue()); |
| + } |
| + |
| + if (show) { |
| + widget_->Activate(); |
| + widget_->Show(); |
| + animation_->Show(); |
| + } else { |
| + animation_->Hide(); |
| + } |
| + } else { |
| + SetAnimationProgress(1.0); |
| + |
| + if (show) { |
| + widget_->Activate(); |
| + widget_->Show(); |
| + } else { |
| + widget_->Hide(); |
| + } |
| + } |
| +} |
| + |
| +bool AppListWindow::IsShowing() const { |
| + if (animation_.get() && animation_->is_animating()) { |
| + return animation_->IsShowing(); |
| + } else { |
| + return widget_->IsVisible(); |
| + } |
| +} |
| + |
| +void AppListWindow::SetAnimationProgress(double progress) { |
| + widget_->SetOpacity(progress * 255); |
| + |
| + gfx::Rect frame = GetPreferredPosition(); |
| + frame.Offset(0, kMoveUpAnimationOffset * (1.0 - progress)); |
| + widget_->SetBounds(frame); |
| +} |
| + |
| +// static |
| +void AppListWindow::Toggle() { |
|
sky
2011/10/25 17:59:27
Make order of methods match order in header.
xiyuan
2011/10/27 22:51:29
Done.
|
| + if (!instance_) { |
| + // TODO(xiyuan): Fix first time animation jankiness. |
| + instance_ = new AppListWindow; |
| + instance_->Init(); |
| + } |
| + |
| + instance_->Show(!instance_->IsShowing(), true); |
| +} |