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
}
}