1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/shelf/shelf.h"
10 #include "ash/focus_cycler.h"
11 #include "ash/root_window_controller.h"
12 #include "ash/screen_util.h"
13 #include "ash/shelf/shelf_delegate.h"
14 #include "ash/shelf/shelf_item_delegate.h"
15 #include "ash/shelf/shelf_item_delegate_manager.h"
16 #include "ash/shelf/shelf_layout_manager.h"
17 #include "ash/shelf/shelf_model.h"
18 #include "ash/shelf/shelf_navigator.h"
19 #include "ash/shelf/shelf_util.h"
20 #include "ash/shelf/shelf_view.h"
21 #include "ash/shelf/shelf_widget.h"
22 #include "ash/shell.h"
23 #include "ash/shell_delegate.h"
24 #include "ash/shell_window_ids.h"
25 #include "ash/wm/window_properties.h"
26 #include "grit/ash_resources.h"
27 #include "ui/aura/window.h"
28 #include "ui/aura/window_event_dispatcher.h"
29 #include "ui/aura/window_observer.h"
30 #include "ui/compositor/layer.h"
31 #include "ui/gfx/canvas.h"
32 #include "ui/gfx/image/image.h"
33 #include "ui/gfx/image/image_skia_operations.h"
34 #include "ui/gfx/skbitmap_operations.h"
35 #include "ui/views/accessible_pane_view.h"
36 #include "ui/views/widget/widget.h"
37 #include "ui/views/widget/widget_delegate.h"
38 #include "ui/wm/public/activation_client.h"
42 const char Shelf::kNativeViewName
[] = "ShelfView";
44 Shelf::Shelf(ShelfModel
* shelf_model
,
45 ShelfDelegate
* shelf_delegate
,
46 ShelfWidget
* shelf_widget
)
48 alignment_(shelf_widget
->GetAlignment()),
49 delegate_(shelf_delegate
),
50 shelf_widget_(shelf_widget
) {
51 shelf_view_
= new ShelfView(
52 shelf_model
, delegate_
, shelf_widget_
->shelf_layout_manager());
54 shelf_widget_
->GetContentsView()->AddChildView(shelf_view_
);
55 shelf_widget_
->GetNativeView()->SetName(kNativeViewName
);
56 delegate_
->OnShelfCreated(this);
60 delegate_
->OnShelfDestroyed(this);
64 Shelf
* Shelf::ForPrimaryDisplay() {
65 ShelfWidget
* shelf_widget
=
66 RootWindowController::ForShelf(Shell::GetPrimaryRootWindow())->shelf();
67 return shelf_widget
? shelf_widget
->shelf() : NULL
;
71 Shelf
* Shelf::ForWindow(aura::Window
* window
) {
72 ShelfWidget
* shelf_widget
= RootWindowController::ForShelf(window
)->shelf();
73 return shelf_widget
? shelf_widget
->shelf() : NULL
;
76 void Shelf::SetAlignment(ShelfAlignment alignment
) {
77 alignment_
= alignment
;
78 shelf_view_
->OnShelfAlignmentChanged();
79 // ShelfLayoutManager will resize the shelf.
82 gfx::Rect
Shelf::GetScreenBoundsOfItemIconForWindow(
83 const aura::Window
* window
) {
84 ShelfID id
= GetShelfIDForWindow(window
);
85 gfx::Rect
bounds(shelf_view_
->GetIdealBoundsOfItemIcon(id
));
86 gfx::Point screen_origin
;
87 views::View::ConvertPointToScreen(shelf_view_
, &screen_origin
);
88 return gfx::Rect(screen_origin
.x() + bounds
.x(),
89 screen_origin
.y() + bounds
.y(),
94 void Shelf::UpdateIconPositionForWindow(aura::Window
* window
) {
95 shelf_view_
->UpdatePanelIconPosition(
96 GetShelfIDForWindow(window
),
97 ScreenUtil::ConvertRectFromScreen(
98 shelf_widget()->GetNativeView(),
99 window
->GetBoundsInScreen()).CenterPoint());
102 void Shelf::ActivateShelfItem(int index
) {
103 // We pass in a keyboard event which will then trigger a switch to the
104 // next item if the current one is already active.
105 ui::KeyEvent
event(ui::ET_KEY_RELEASED
,
106 ui::VKEY_UNKNOWN
, // The actual key gets ignored.
109 const ShelfItem
& item
= shelf_view_
->model()->items()[index
];
110 ShelfItemDelegate
* item_delegate
=
111 Shell::GetInstance()->shelf_item_delegate_manager()->GetShelfItemDelegate(
113 item_delegate
->ItemSelected(event
);
116 void Shelf::CycleWindowLinear(CycleDirection direction
) {
117 int item_index
= GetNextActivatedItemIndex(
118 *(shelf_view_
->model()), direction
);
120 ActivateShelfItem(item_index
);
123 void Shelf::AddIconObserver(ShelfIconObserver
* observer
) {
124 shelf_view_
->AddIconObserver(observer
);
127 void Shelf::RemoveIconObserver(ShelfIconObserver
* observer
) {
128 shelf_view_
->RemoveIconObserver(observer
);
131 bool Shelf::IsShowingMenu() const {
132 return shelf_view_
->IsShowingMenu();
135 bool Shelf::IsShowingOverflowBubble() const {
136 return shelf_view_
->IsShowingOverflowBubble();
139 void Shelf::SetVisible(bool visible
) const {
140 shelf_view_
->SetVisible(visible
);
143 bool Shelf::IsVisible() const {
144 return shelf_view_
->visible();
147 void Shelf::SchedulePaint() {
148 shelf_view_
->SchedulePaintForAllButtons();
151 views::View
* Shelf::GetAppListButtonView() const {
152 return shelf_view_
->GetAppListButtonView();
155 void Shelf::LaunchAppIndexAt(int item_index
) {
156 ShelfModel
* shelf_model
= shelf_view_
->model();
157 const ShelfItems
& items
= shelf_model
->items();
158 int item_count
= shelf_model
->item_count();
159 int indexes_left
= item_index
>= 0 ? item_index
: item_count
;
160 int found_index
= -1;
162 // Iterating until we have hit the index we are interested in which
163 // is true once indexes_left becomes negative.
164 for (int i
= 0; i
< item_count
&& indexes_left
>= 0; i
++) {
165 if (items
[i
].type
!= TYPE_APP_LIST
) {
171 // There are two ways how found_index can be valid: a.) the nth item was
172 // found (which is true when indexes_left is -1) or b.) the last item was
173 // requested (which is true when index was passed in as a negative number).
174 if (found_index
>= 0 && (indexes_left
== -1 || item_index
< 0)) {
175 // Then set this one as active (or advance to the next item of its kind).
176 ActivateShelfItem(found_index
);
180 void Shelf::SetShelfViewBounds(gfx::Rect bounds
) {
181 shelf_view_
->SetBoundsRect(bounds
);
184 gfx::Rect
Shelf::GetShelfViewBounds() const {
185 return shelf_view_
->bounds();
188 gfx::Rect
Shelf::GetVisibleItemsBoundsInScreen() const {
189 return shelf_view_
->GetVisibleItemsBoundsInScreen();
192 app_list::ApplicationDragAndDropHost
* Shelf::GetDragAndDropHostForAppList() {