Commit 46972105 authored by xiyuan@chromium.org's avatar xiyuan@chromium.org

[Aura] Update app list window.

- Defer showing animation until web contents is rendered;
- Properly close widget after hiding animation is finished;
- Create app list window with always-on-top and transparent flags;

BUG=98308
TEST=Verify showing animation could be seen.


Review URL: http://codereview.chromium.org/8469019

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@109785 0039d316-1c4b-4281-b951-d872f2087c98
parent 2f451516
......@@ -32,6 +32,10 @@ gfx::Rect GetPreferredBounds(bool show) {
return widget_bounds;
}
ui::Layer* GetWidgetLayer(views::Widget* widget) {
return widget->GetNativeView()->layer();
}
} // namespace
// static
......@@ -40,22 +44,23 @@ AppListWindow* AppListWindow::instance_ = NULL;
// static
void AppListWindow::SetVisible(bool visible) {
if (!instance_) {
// TODO(xiyuan): Fix first time animation jankiness.
instance_ = new AppListWindow;
instance_->Init();
}
instance_->SetVisible(visible, true);
instance_->DoSetVisible(visible);
}
// static
bool AppListWindow::IsVisible() {
return instance_ && instance_->is_visible();
return instance_ && instance_->is_visible_;
}
AppListWindow::AppListWindow()
: widget_(NULL),
contents_(NULL),
is_visible_(false) {
is_visible_(false),
content_rendered_(false) {
}
AppListWindow::~AppListWindow() {
......@@ -84,7 +89,37 @@ const views::Widget* AppListWindow::GetWidget() const {
void AppListWindow::OnActiveWindowChanged(aura::Window* active) {
if (widget_ && !widget_->IsActive() && is_visible_)
SetVisible(false, true);
DoSetVisible(false);
}
void AppListWindow::OnLayerAnimationEnded(
const ui::LayerAnimationSequence* sequence) {
if (!is_visible_ )
widget_->Close();
}
void AppListWindow::OnLayerAnimationAborted(
const ui::LayerAnimationSequence* sequence) {
}
void AppListWindow::OnLayerAnimationScheduled(
const ui::LayerAnimationSequence* sequence) {
}
void AppListWindow::OnRenderHostCreated(RenderViewHost* host) {
}
void AppListWindow::OnTabMainFrameLoaded() {
}
void AppListWindow::OnTabMainFrameFirstRender() {
content_rendered_ = true;
// Do deferred show animation if necessary.
if (is_visible_ && GetWidgetLayer(widget_)->opacity() == 0) {
is_visible_ = false;
DoSetVisible(true);
}
}
void AppListWindow::Init() {
......@@ -92,6 +127,11 @@ void AppListWindow::Init() {
contents_ = new DOMView();
contents_->Init(ProfileManager::GetDefaultProfile(), NULL);
TabContents* tab = contents_->dom_contents()->tab_contents();
tab_watcher_.reset(new TabFirstRenderWatcher(tab, this));
content_rendered_ = false;
contents_->LoadURL(GURL(chrome::kChromeUIAppListURL));
// Use a background with transparency to trigger transparent webkit.
......@@ -100,7 +140,6 @@ void AppListWindow::Init() {
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);
......@@ -108,45 +147,38 @@ void AppListWindow::Init() {
views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
widget_params.bounds = GetPreferredBounds(false);
widget_params.delegate = this;
widget_params.keep_on_top = true;
widget_params.transparent = true;
widget_ = new views::Widget;
widget_->Init(widget_params);
widget_->SetContentsView(contents_);
widget_->SetOpacity(0);
GetWidgetLayer(widget_)->GetAnimator()->AddObserver(this);
aura::Desktop::GetInstance()->AddObserver(this);
}
void AppListWindow::SetVisible(bool visible, bool animate) {
void AppListWindow::DoSetVisible(bool visible) {
if (visible == is_visible_)
return;
is_visible_ = visible;
if (animate) {
gfx::Point dummy;
ui::Layer* layer;
widget_->CalculateOffsetToAncestorWithLayer(&dummy, &layer);
// Skip show animation if contents is not rendered.
// TODO(xiyuan): Should we show a loading UI if it takes too long?
if (visible && !content_rendered_)
return;
ui::Layer* layer = GetWidgetLayer(widget_);
ui::LayerAnimator::ScopedSettings settings(layer->GetAnimator());
layer->SetBounds(GetPreferredBounds(visible));
layer->SetOpacity(visible ? 1.0 : 0.0);
}
if (visible) {
widget_->Activate();
widget_->Show();
widget_->Activate();
} else {
instance_ = NULL; // Closing and don't reuse this instance_.
if (animate) {
// TODO(xiyuan): Properly close widget after animation finishes.
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&views::Widget::Close, base::Unretained(widget_)),
1000);
} else {
widget_->Close();
}
}
}
......@@ -6,7 +6,10 @@
#define CHROME_BROWSER_UI_VIEWS_AURA_APP_LIST_WINDOW_H_
#pragma once
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/tab_first_render_watcher.h"
#include "ui/aura/desktop_observer.h"
#include "ui/gfx/compositor/layer_animation_observer.h"
#include "views/widget/widget_delegate.h"
class DOMView;
......@@ -16,7 +19,9 @@ class Widget;
}
class AppListWindow : public views::WidgetDelegate,
public aura::DesktopObserver {
public aura::DesktopObserver,
public ui::LayerAnimationObserver,
public TabFirstRenderWatcher::Delegate {
public:
// Show/hide app list window.
static void SetVisible(bool visible);
......@@ -28,7 +33,7 @@ class AppListWindow : public views::WidgetDelegate,
AppListWindow();
virtual ~AppListWindow();
// Overridden from views::WidgetDelegate:
// views::WidgetDelegate overrides:
virtual void DeleteDelegate() OVERRIDE;
virtual views::View* GetContentsView() OVERRIDE;
virtual void WindowClosing() OVERRIDE;
......@@ -38,15 +43,24 @@ class AppListWindow : public views::WidgetDelegate,
// aura::DesktopObserver overrides:
virtual void OnActiveWindowChanged(aura::Window* active) OVERRIDE;
// ui::LayerAnimationObserver overrides:
virtual void OnLayerAnimationEnded(
const ui::LayerAnimationSequence* sequence) OVERRIDE;
virtual void OnLayerAnimationAborted(
const ui::LayerAnimationSequence* sequence) OVERRIDE;
virtual void OnLayerAnimationScheduled(
const ui::LayerAnimationSequence* sequence) OVERRIDE;
// TabFirstRenderWatcher::Delegate implementation:
virtual void OnRenderHostCreated(RenderViewHost* host) OVERRIDE;
virtual void OnTabMainFrameLoaded() OVERRIDE;
virtual void OnTabMainFrameFirstRender() OVERRIDE;
// Initializes the window.
void Init();
// Shows/hides the window.
void SetVisible(bool visible, bool animate);
bool is_visible() const {
return is_visible_;
}
void DoSetVisible(bool visible);
// Current visible app list window.
static AppListWindow* instance_;
......@@ -55,6 +69,13 @@ class AppListWindow : public views::WidgetDelegate,
DOMView* contents_;
bool is_visible_;
// Monitors TabContents and set |content_rendered_| flag when it's rendered.
scoped_ptr<TabFirstRenderWatcher> tab_watcher_;
// Flag of whether the web contents is rendered. Showing animation is
// deferred until this flag is set to true.
bool content_rendered_;
DISALLOW_COPY_AND_ASSIGN(AppListWindow);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment