root/ash/shelf/shelf.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. shelf_widget_
  2. ForPrimaryDisplay
  3. ForWindow
  4. SetAlignment
  5. GetScreenBoundsOfItemIconForWindow
  6. UpdateIconPositionForWindow
  7. ActivateShelfItem
  8. CycleWindowLinear
  9. AddIconObserver
  10. RemoveIconObserver
  11. IsShowingMenu
  12. IsShowingOverflowBubble
  13. SetVisible
  14. IsVisible
  15. SchedulePaint
  16. GetAppListButtonView
  17. LaunchAppIndexAt
  18. SetShelfViewBounds
  19. GetShelfViewBounds
  20. GetVisibleItemsBoundsInScreen
  21. GetDragAndDropHostForAppList

// Copyright 2013 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 "ash/shelf/shelf.h"

#include <algorithm>
#include <cmath>

#include "ash/focus_cycler.h"
#include "ash/root_window_controller.h"
#include "ash/screen_util.h"
#include "ash/shelf/shelf_delegate.h"
#include "ash/shelf/shelf_item_delegate.h"
#include "ash/shelf/shelf_item_delegate_manager.h"
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shelf/shelf_model.h"
#include "ash/shelf/shelf_navigator.h"
#include "ash/shelf/shelf_util.h"
#include "ash/shelf/shelf_view.h"
#include "ash/shelf/shelf_widget.h"
#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/window_properties.h"
#include "grit/ash_resources.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_observer.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/skbitmap_operations.h"
#include "ui/views/accessible_pane_view.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/wm/public/activation_client.h"

namespace ash {

const char Shelf::kNativeViewName[] = "ShelfView";

Shelf::Shelf(ShelfModel* shelf_model,
             ShelfDelegate* shelf_delegate,
             ShelfWidget* shelf_widget)
    : shelf_view_(NULL),
      alignment_(shelf_widget->GetAlignment()),
      delegate_(shelf_delegate),
      shelf_widget_(shelf_widget) {
  shelf_view_ = new ShelfView(
      shelf_model, delegate_, shelf_widget_->shelf_layout_manager());
  shelf_view_->Init();
  shelf_widget_->GetContentsView()->AddChildView(shelf_view_);
  shelf_widget_->GetNativeView()->SetName(kNativeViewName);
  delegate_->OnShelfCreated(this);
}

Shelf::~Shelf() {
  delegate_->OnShelfDestroyed(this);
}

// static
Shelf* Shelf::ForPrimaryDisplay() {
  ShelfWidget* shelf_widget =
      RootWindowController::ForShelf(Shell::GetPrimaryRootWindow())->shelf();
  return shelf_widget ? shelf_widget->shelf() : NULL;
}

// static
Shelf* Shelf::ForWindow(aura::Window* window) {
  ShelfWidget* shelf_widget = RootWindowController::ForShelf(window)->shelf();
  return shelf_widget ? shelf_widget->shelf() : NULL;
}

void Shelf::SetAlignment(ShelfAlignment alignment) {
  alignment_ = alignment;
  shelf_view_->OnShelfAlignmentChanged();
  // ShelfLayoutManager will resize the shelf.
}

gfx::Rect Shelf::GetScreenBoundsOfItemIconForWindow(aura::Window* window) {
  ShelfID id = GetShelfIDForWindow(window);
  gfx::Rect bounds(shelf_view_->GetIdealBoundsOfItemIcon(id));
  gfx::Point screen_origin;
  views::View::ConvertPointToScreen(shelf_view_, &screen_origin);
  return gfx::Rect(screen_origin.x() + bounds.x(),
                   screen_origin.y() + bounds.y(),
                   bounds.width(),
                   bounds.height());
}

void Shelf::UpdateIconPositionForWindow(aura::Window* window) {
  shelf_view_->UpdatePanelIconPosition(
      GetShelfIDForWindow(window),
      ScreenUtil::ConvertRectFromScreen(
          shelf_widget()->GetNativeView(),
          window->GetBoundsInScreen()).CenterPoint());
}

void Shelf::ActivateShelfItem(int index) {
  // We pass in a keyboard event which will then trigger a switch to the
  // next item if the current one is already active.
  ui::KeyEvent event(ui::ET_KEY_RELEASED,
                     ui::VKEY_UNKNOWN,  // The actual key gets ignored.
                     ui::EF_NONE,
                     false);

  const ShelfItem& item = shelf_view_->model()->items()[index];
  ShelfItemDelegate* item_delegate =
      Shell::GetInstance()->shelf_item_delegate_manager()->GetShelfItemDelegate(
          item.id);
  item_delegate->ItemSelected(event);
}

void Shelf::CycleWindowLinear(CycleDirection direction) {
  int item_index = GetNextActivatedItemIndex(
      *(shelf_view_->model()), direction);
  if (item_index >= 0)
    ActivateShelfItem(item_index);
}

void Shelf::AddIconObserver(ShelfIconObserver* observer) {
  shelf_view_->AddIconObserver(observer);
}

void Shelf::RemoveIconObserver(ShelfIconObserver* observer) {
  shelf_view_->RemoveIconObserver(observer);
}

bool Shelf::IsShowingMenu() const {
  return shelf_view_->IsShowingMenu();
}

bool Shelf::IsShowingOverflowBubble() const {
  return shelf_view_->IsShowingOverflowBubble();
}

void Shelf::SetVisible(bool visible) const {
  shelf_view_->SetVisible(visible);
}

bool Shelf::IsVisible() const {
  return shelf_view_->visible();
}

void Shelf::SchedulePaint() {
  shelf_view_->SchedulePaintForAllButtons();
}

views::View* Shelf::GetAppListButtonView() const {
  return shelf_view_->GetAppListButtonView();
}

void Shelf::LaunchAppIndexAt(int item_index) {
  ShelfModel* shelf_model = shelf_view_->model();
  const ShelfItems& items = shelf_model->items();
  int item_count = shelf_model->item_count();
  int indexes_left = item_index >= 0 ? item_index : item_count;
  int found_index = -1;

  // Iterating until we have hit the index we are interested in which
  // is true once indexes_left becomes negative.
  for (int i = 0; i < item_count && indexes_left >= 0; i++) {
    if (items[i].type != TYPE_APP_LIST) {
      found_index = i;
      indexes_left--;
    }
  }

  // There are two ways how found_index can be valid: a.) the nth item was
  // found (which is true when indexes_left is -1) or b.) the last item was
  // requested (which is true when index was passed in as a negative number).
  if (found_index >= 0 && (indexes_left == -1 || item_index < 0)) {
    // Then set this one as active (or advance to the next item of its kind).
    ActivateShelfItem(found_index);
  }
}

void Shelf::SetShelfViewBounds(gfx::Rect bounds) {
  shelf_view_->SetBoundsRect(bounds);
}

gfx::Rect Shelf::GetShelfViewBounds() const {
  return shelf_view_->bounds();
}

gfx::Rect Shelf::GetVisibleItemsBoundsInScreen() const {
  return shelf_view_->GetVisibleItemsBoundsInScreen();
}

app_list::ApplicationDragAndDropHost* Shelf::GetDragAndDropHostForAppList() {
  return shelf_view_;
}

}  // namespace ash

/* [<][>][^][v][top][bottom][index][help] */