This source file includes following definitions.
- SupportsShadow
- target_
- SetTarget
- set_frame
- OnImplicitAnimationsCompleted
- animation_observer_
- InitAsBubbleAttachedToAnchor
- InitAsBubbleAtFixedLocation
- SetBubbleArrow
- SetAnchorPoint
- SetDragAndDropHostOfCurrentAppList
- ShowWhenReady
- Close
- UpdateBounds
- GetPreferredSize
- Paint
- OnThemeChanged
- ShouldHandleSystemCommands
- Prerender
- OnProfilesChanged
- SetProfileByPath
- AddObserver
- RemoveObserver
- SetNextPaintCallback
- GetHWND
- InitAsBubbleInternal
- OnBeforeBubbleWidgetInit
- GetInitiallyFocusedView
- GetWindowIcon
- WidgetHasHitTestMask
- GetWidgetHitTestMask
- AcceleratorPressed
- Layout
- SchedulePaintInRect
- OnWidgetDestroying
- OnWidgetActivationChanged
- OnWidgetVisibilityChanged
- OnSpeechRecognitionStateChanged
#include "ui/app_list/views/app_list_view.h"
#include <algorithm>
#include "base/command_line.h"
#include "base/strings/string_util.h"
#include "base/win/windows_version.h"
#include "ui/app_list/app_list_constants.h"
#include "ui/app_list/app_list_model.h"
#include "ui/app_list/app_list_view_delegate.h"
#include "ui/app_list/pagination_model.h"
#include "ui/app_list/signin_delegate.h"
#include "ui/app_list/speech_ui_model.h"
#include "ui/app_list/views/app_list_background.h"
#include "ui/app_list/views/app_list_folder_view.h"
#include "ui/app_list/views/app_list_main_view.h"
#include "ui/app_list/views/app_list_view_observer.h"
#include "ui/app_list/views/apps_container_view.h"
#include "ui/app_list/views/contents_view.h"
#include "ui/app_list/views/search_box_view.h"
#include "ui/app_list/views/signin_view.h"
#include "ui/app_list/views/speech_view.h"
#include "ui/base/ui_base_switches.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/insets.h"
#include "ui/gfx/path.h"
#include "ui/gfx/skia_util.h"
#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/bubble/bubble_window_targeter.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/widget.h"
#if defined(USE_AURA)
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#if defined(OS_WIN)
#include "ui/base/win/shell.h"
#endif
#if !defined(OS_CHROMEOS)
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
#endif
#endif
namespace app_list {
namespace {
void (*g_next_paint_callback)();
const int kSpeechUIMargin = 12;
const float kSpeechUIAppearingPosition = 12;
const int kArrowOffset = 10;
bool SupportsShadow() {
#if defined(OS_WIN)
if (!ui::win::IsAeroGlassEnabled() ||
CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableDwmComposition)) {
return false;
}
#elif defined(OS_LINUX) && !defined(USE_ASH)
return false;
#endif
return true;
}
}
class HideViewAnimationObserver : public ui::ImplicitAnimationObserver {
public:
HideViewAnimationObserver()
: frame_(NULL),
target_(NULL) {
}
virtual ~HideViewAnimationObserver() {
if (target_)
StopObservingImplicitAnimations();
}
void SetTarget(views::View* target) {
if (!target_)
StopObservingImplicitAnimations();
target_ = target;
}
void set_frame(views::BubbleFrameView* frame) { frame_ = frame; }
private:
virtual void OnImplicitAnimationsCompleted() OVERRIDE {
if (target_) {
target_->SetVisible(false);
target_ = NULL;
frame_->SchedulePaint();
}
}
views::BubbleFrameView* frame_;
views::View* target_;
DISALLOW_COPY_AND_ASSIGN(HideViewAnimationObserver);
};
AppListView::AppListView(AppListViewDelegate* delegate)
: delegate_(delegate),
app_list_main_view_(NULL),
signin_view_(NULL),
speech_view_(NULL),
animation_observer_(new HideViewAnimationObserver()) {
CHECK(delegate);
delegate_->AddObserver(this);
delegate_->GetSpeechUI()->AddObserver(this);
}
AppListView::~AppListView() {
delegate_->GetSpeechUI()->RemoveObserver(this);
delegate_->RemoveObserver(this);
animation_observer_.reset();
RemoveAllChildViews(true);
}
void AppListView::InitAsBubbleAttachedToAnchor(
gfx::NativeView parent,
PaginationModel* pagination_model,
views::View* anchor,
const gfx::Vector2d& anchor_offset,
views::BubbleBorder::Arrow arrow,
bool border_accepts_events) {
SetAnchorView(anchor);
InitAsBubbleInternal(
parent, pagination_model, arrow, border_accepts_events, anchor_offset);
}
void AppListView::InitAsBubbleAtFixedLocation(
gfx::NativeView parent,
PaginationModel* pagination_model,
const gfx::Point& anchor_point_in_screen,
views::BubbleBorder::Arrow arrow,
bool border_accepts_events) {
SetAnchorView(NULL);
SetAnchorRect(gfx::Rect(anchor_point_in_screen, gfx::Size()));
InitAsBubbleInternal(
parent, pagination_model, arrow, border_accepts_events, gfx::Vector2d());
}
void AppListView::SetBubbleArrow(views::BubbleBorder::Arrow arrow) {
GetBubbleFrameView()->bubble_border()->set_arrow(arrow);
SizeToContents();
GetBubbleFrameView()->SchedulePaint();
}
void AppListView::SetAnchorPoint(const gfx::Point& anchor_point) {
SetAnchorRect(gfx::Rect(anchor_point, gfx::Size()));
}
void AppListView::SetDragAndDropHostOfCurrentAppList(
ApplicationDragAndDropHost* drag_and_drop_host) {
app_list_main_view_->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host);
}
void AppListView::ShowWhenReady() {
app_list_main_view_->ShowAppListWhenReady();
}
void AppListView::Close() {
app_list_main_view_->Close();
delegate_->Dismiss();
}
void AppListView::UpdateBounds() {
SizeToContents();
}
gfx::Size AppListView::GetPreferredSize() {
return app_list_main_view_->GetPreferredSize();
}
void AppListView::Paint(gfx::Canvas* canvas) {
views::BubbleDelegateView::Paint(canvas);
if (g_next_paint_callback) {
g_next_paint_callback();
g_next_paint_callback = NULL;
}
}
void AppListView::OnThemeChanged() {
#if defined(OS_WIN)
GetWidget()->Close();
#endif
}
bool AppListView::ShouldHandleSystemCommands() const {
return true;
}
void AppListView::Prerender() {
app_list_main_view_->Prerender();
}
void AppListView::OnProfilesChanged() {
SigninDelegate* signin_delegate =
delegate_ ? delegate_->GetSigninDelegate() : NULL;
bool show_signin_view = signin_delegate && signin_delegate->NeedSignin();
signin_view_->SetVisible(show_signin_view);
app_list_main_view_->SetVisible(!show_signin_view);
app_list_main_view_->search_box_view()->InvalidateMenu();
}
void AppListView::SetProfileByPath(const base::FilePath& profile_path) {
delegate_->SetProfileByPath(profile_path);
app_list_main_view_->ModelChanged();
}
void AppListView::AddObserver(AppListViewObserver* observer) {
observers_.AddObserver(observer);
}
void AppListView::RemoveObserver(AppListViewObserver* observer) {
observers_.RemoveObserver(observer);
}
void AppListView::SetNextPaintCallback(void (*callback)()) {
g_next_paint_callback = callback;
}
#if defined(OS_WIN)
HWND AppListView::GetHWND() const {
#if defined(USE_AURA)
gfx::NativeWindow window =
GetWidget()->GetTopLevelWidget()->GetNativeWindow();
return window->GetHost()->GetAcceleratedWidget();
#else
return GetWidget()->GetTopLevelWidget()->GetNativeWindow();
#endif
}
#endif
void AppListView::InitAsBubbleInternal(gfx::NativeView parent,
PaginationModel* pagination_model,
views::BubbleBorder::Arrow arrow,
bool border_accepts_events,
const gfx::Vector2d& anchor_offset) {
app_list_main_view_ = new AppListMainView(delegate_.get(),
pagination_model,
parent);
AddChildView(app_list_main_view_);
#if defined(USE_AURA)
app_list_main_view_->SetPaintToLayer(true);
app_list_main_view_->SetFillsBoundsOpaquely(false);
app_list_main_view_->layer()->SetMasksToBounds(true);
#endif
signin_view_ =
new SigninView(delegate_->GetSigninDelegate(),
app_list_main_view_->GetPreferredSize().width());
AddChildView(signin_view_);
if (delegate_ && delegate_->GetSpeechRecognitionContents()) {
speech_view_ = new SpeechView(delegate_.get());
speech_view_->SetVisible(false);
#if defined(USE_AURA)
speech_view_->SetPaintToLayer(true);
speech_view_->SetFillsBoundsOpaquely(false);
speech_view_->layer()->SetOpacity(0.0f);
#endif
AddChildView(speech_view_);
}
OnProfilesChanged();
set_color(kContentsBackgroundColor);
set_margins(gfx::Insets());
set_move_with_anchor(true);
set_parent_window(parent);
set_close_on_deactivate(false);
set_close_on_esc(false);
set_anchor_view_insets(gfx::Insets(kArrowOffset + anchor_offset.y(),
kArrowOffset + anchor_offset.x(),
kArrowOffset - anchor_offset.y(),
kArrowOffset - anchor_offset.x()));
set_border_accepts_events(border_accepts_events);
set_shadow(SupportsShadow() ? views::BubbleBorder::BIG_SHADOW
: views::BubbleBorder::NO_SHADOW_OPAQUE_BORDER);
views::BubbleDelegateView::CreateBubble(this);
SetBubbleArrow(arrow);
#if defined(USE_AURA)
aura::Window* window = GetWidget()->GetNativeWindow();
window->layer()->SetMasksToBounds(true);
GetBubbleFrameView()->set_background(new AppListBackground(
GetBubbleFrameView()->bubble_border()->GetBorderCornerRadius(),
app_list_main_view_));
set_background(NULL);
window->SetEventTargeter(scoped_ptr<ui::EventTargeter>(
new views::BubbleWindowTargeter(this)));
#else
set_background(new AppListBackground(
GetBubbleFrameView()->bubble_border()->GetBorderCornerRadius(),
app_list_main_view_));
GetWidget()->Hide();
#endif
if (delegate_)
delegate_->ViewInitialized();
}
void AppListView::OnBeforeBubbleWidgetInit(
views::Widget::InitParams* params,
views::Widget* widget) const {
#if defined(USE_AURA) && !defined(OS_CHROMEOS)
if (delegate_ && delegate_->ForceNativeDesktop())
params->native_widget = new views::DesktopNativeWidgetAura(widget);
#endif
#if defined(OS_WIN)
if (base::win::GetVersion() >= base::win::VERSION_WIN7)
params->force_show_in_taskbar = true;
#elif defined(OS_LINUX)
params->wm_class_name = kAppListWMClass;
params->force_show_in_taskbar = true;
#endif
}
views::View* AppListView::GetInitiallyFocusedView() {
return app_list_main_view_->search_box_view()->search_box();
}
gfx::ImageSkia AppListView::GetWindowIcon() {
if (delegate_)
return delegate_->GetWindowIcon();
return gfx::ImageSkia();
}
bool AppListView::WidgetHasHitTestMask() const {
return true;
}
void AppListView::GetWidgetHitTestMask(gfx::Path* mask) const {
DCHECK(mask);
mask->addRect(gfx::RectToSkRect(
GetBubbleFrameView()->GetContentsBounds()));
}
bool AppListView::AcceleratorPressed(const ui::Accelerator& accelerator) {
if (accelerator.key_code() == ui::VKEY_ESCAPE) {
if (app_list_main_view_->search_box_view()->HasSearch()) {
app_list_main_view_->search_box_view()->ClearSearch();
} else if (app_list_main_view_->contents_view()
->apps_container_view()
->IsInFolderView()) {
app_list_main_view_->contents_view()
->apps_container_view()
->app_list_folder_view()
->CloseFolderPage();
return true;
} else {
GetWidget()->Deactivate();
Close();
}
return true;
}
return false;
}
void AppListView::Layout() {
const gfx::Rect contents_bounds = GetContentsBounds();
app_list_main_view_->SetBoundsRect(contents_bounds);
signin_view_->SetBoundsRect(contents_bounds);
if (speech_view_) {
gfx::Rect speech_bounds = contents_bounds;
int preferred_height = speech_view_->GetPreferredSize().height();
speech_bounds.Inset(kSpeechUIMargin, kSpeechUIMargin);
speech_bounds.set_height(std::min(speech_bounds.height(),
preferred_height));
speech_bounds.Inset(-speech_view_->GetInsets());
speech_view_->SetBoundsRect(speech_bounds);
}
}
void AppListView::SchedulePaintInRect(const gfx::Rect& rect) {
BubbleDelegateView::SchedulePaintInRect(rect);
if (GetBubbleFrameView())
GetBubbleFrameView()->SchedulePaint();
}
void AppListView::OnWidgetDestroying(views::Widget* widget) {
BubbleDelegateView::OnWidgetDestroying(widget);
if (delegate_ && widget == GetWidget())
delegate_->ViewClosing();
}
void AppListView::OnWidgetActivationChanged(views::Widget* widget,
bool active) {
if (widget == GetWidget())
FOR_EACH_OBSERVER(AppListViewObserver, observers_,
OnActivationChanged(widget, active));
}
void AppListView::OnWidgetVisibilityChanged(views::Widget* widget,
bool visible) {
BubbleDelegateView::OnWidgetVisibilityChanged(widget, visible);
if (widget != GetWidget())
return;
if (!visible)
app_list_main_view_->ResetForShow();
Layout();
}
void AppListView::OnSpeechRecognitionStateChanged(
SpeechRecognitionState new_state) {
if (signin_view_->visible() || !speech_view_)
return;
bool recognizing = (new_state == SPEECH_RECOGNITION_RECOGNIZING ||
new_state == SPEECH_RECOGNITION_IN_SPEECH);
if (speech_view_->visible() == recognizing)
return;
if (recognizing)
speech_view_->Reset();
#if defined(USE_AURA)
animation_observer_->set_frame(GetBubbleFrameView());
gfx::Transform speech_transform;
speech_transform.Translate(
0, SkFloatToMScalar(kSpeechUIAppearingPosition));
if (recognizing)
speech_view_->layer()->SetTransform(speech_transform);
{
ui::ScopedLayerAnimationSettings main_settings(
app_list_main_view_->layer()->GetAnimator());
if (recognizing) {
animation_observer_->SetTarget(app_list_main_view_);
main_settings.AddObserver(animation_observer_.get());
}
app_list_main_view_->layer()->SetOpacity(recognizing ? 0.0f : 1.0f);
}
{
ui::ScopedLayerAnimationSettings speech_settings(
speech_view_->layer()->GetAnimator());
if (!recognizing) {
animation_observer_->SetTarget(speech_view_);
speech_settings.AddObserver(animation_observer_.get());
}
speech_view_->layer()->SetOpacity(recognizing ? 1.0f : 0.0f);
if (recognizing)
speech_view_->layer()->SetTransform(gfx::Transform());
else
speech_view_->layer()->SetTransform(speech_transform);
}
if (recognizing)
speech_view_->SetVisible(true);
else
app_list_main_view_->SetVisible(true);
#else
speech_view_->SetVisible(recognizing);
app_list_main_view_->SetVisible(!recognizing);
GetBubbleFrameView()->SchedulePaint();
#endif
}
}