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 "ui/aura/window.h"
27 #include "ui/aura/window_event_dispatcher.h"
28 #include "ui/aura/window_observer.h"
29 #include "ui/compositor/layer.h"
30 #include "ui/gfx/canvas.h"
31 #include "ui/gfx/image/image.h"
32 #include "ui/gfx/image/image_skia_operations.h"
33 #include "ui/gfx/skbitmap_operations.h"
34 #include "ui/views/accessible_pane_view.h"
35 #include "ui/views/widget/widget.h"
36 #include "ui/views/widget/widget_delegate.h"
37 #include "ui/wm/public/activation_client.h"
41 const char Shelf::kNativeViewName
[] = "ShelfView";
43 Shelf::Shelf(ShelfModel
* shelf_model
,
44 ShelfDelegate
* shelf_delegate
,
45 ShelfWidget
* shelf_widget
)
47 alignment_(shelf_widget
->GetAlignment()),
48 delegate_(shelf_delegate
),
49 shelf_widget_(shelf_widget
) {
50 shelf_view_
= new ShelfView(
51 shelf_model
, delegate_
, shelf_widget_
->shelf_layout_manager());
53 shelf_widget_
->GetContentsView()->AddChildView(shelf_view_
);
54 shelf_widget_
->GetNativeView()->SetName(kNativeViewName
);
55 delegate_
->OnShelfCreated(this);
59 delegate_
->OnShelfDestroyed(this);
63 Shelf
* Shelf::ForPrimaryDisplay() {
64 ShelfWidget
* shelf_widget
=
65 RootWindowController::ForShelf(Shell::GetPrimaryRootWindow())->shelf();
66 return shelf_widget
? shelf_widget
->shelf() : NULL
;
70 Shelf
* Shelf::ForWindow(aura::Window
* window
) {
71 ShelfWidget
* shelf_widget
= RootWindowController::ForShelf(window
)->shelf();
72 return shelf_widget
? shelf_widget
->shelf() : NULL
;
75 void Shelf::SetAlignment(ShelfAlignment alignment
) {
76 alignment_
= alignment
;
77 shelf_view_
->OnShelfAlignmentChanged();
78 // ShelfLayoutManager will resize the shelf.
81 gfx::Rect
Shelf::GetScreenBoundsOfItemIconForWindow(
82 const aura::Window
* window
) {
83 ShelfID id
= GetShelfIDForWindow(window
);
84 gfx::Rect
bounds(shelf_view_
->GetIdealBoundsOfItemIcon(id
));
85 gfx::Point screen_origin
;
86 views::View::ConvertPointToScreen(shelf_view_
, &screen_origin
);
87 return gfx::Rect(screen_origin
.x() + bounds
.x(),
88 screen_origin
.y() + bounds
.y(),
93 void Shelf::UpdateIconPositionForWindow(aura::Window
* window
) {
94 shelf_view_
->UpdatePanelIconPosition(
95 GetShelfIDForWindow(window
),
96 ScreenUtil::ConvertRectFromScreen(
97 shelf_widget()->GetNativeView(),
98 window
->GetBoundsInScreen()).CenterPoint());
101 void Shelf::ActivateShelfItem(int index
) {
102 // We pass in a keyboard event which will then trigger a switch to the
103 // next item if the current one is already active.
104 ui::KeyEvent
event(ui::ET_KEY_RELEASED
,
105 ui::VKEY_UNKNOWN
, // The actual key gets ignored.
108 const ShelfItem
& item
= shelf_view_
->model()->items()[index
];
109 ShelfItemDelegate
* item_delegate
=
110 Shell::GetInstance()->shelf_item_delegate_manager()->GetShelfItemDelegate(
112 item_delegate
->ItemSelected(event
);
115 void Shelf::CycleWindowLinear(CycleDirection direction
) {
116 int item_index
= GetNextActivatedItemIndex(
117 *(shelf_view_
->model()), direction
);
119 ActivateShelfItem(item_index
);
122 void Shelf::AddIconObserver(ShelfIconObserver
* observer
) {
123 shelf_view_
->AddIconObserver(observer
);
126 void Shelf::RemoveIconObserver(ShelfIconObserver
* observer
) {
127 shelf_view_
->RemoveIconObserver(observer
);
130 bool Shelf::IsShowingMenu() const {
131 return shelf_view_
->IsShowingMenu();
134 bool Shelf::IsShowingOverflowBubble() const {
135 return shelf_view_
->IsShowingOverflowBubble();
138 void Shelf::SetVisible(bool visible
) const {
139 shelf_view_
->SetVisible(visible
);
142 bool Shelf::IsVisible() const {
143 return shelf_view_
->visible();
146 void Shelf::SchedulePaint() {
147 shelf_view_
->SchedulePaintForAllButtons();
150 views::View
* Shelf::GetAppListButtonView() const {
151 return shelf_view_
->GetAppListButtonView();
154 void Shelf::LaunchAppIndexAt(int item_index
) {
155 ShelfModel
* shelf_model
= shelf_view_
->model();
156 const ShelfItems
& items
= shelf_model
->items();
157 int item_count
= shelf_model
->item_count();
158 int indexes_left
= item_index
>= 0 ? item_index
: item_count
;
159 int found_index
= -1;
161 // Iterating until we have hit the index we are interested in which
162 // is true once indexes_left becomes negative.
163 for (int i
= 0; i
< item_count
&& indexes_left
>= 0; i
++) {
164 if (items
[i
].type
!= TYPE_APP_LIST
) {
170 // There are two ways how found_index can be valid: a.) the nth item was
171 // found (which is true when indexes_left is -1) or b.) the last item was
172 // requested (which is true when index was passed in as a negative number).
173 if (found_index
>= 0 && (indexes_left
== -1 || item_index
< 0)) {
174 // Then set this one as active (or advance to the next item of its kind).
175 ActivateShelfItem(found_index
);
179 void Shelf::SetShelfViewBounds(gfx::Rect bounds
) {
180 shelf_view_
->SetBoundsRect(bounds
);
183 gfx::Rect
Shelf::GetShelfViewBounds() const {
184 return shelf_view_
->bounds();
187 gfx::Rect
Shelf::GetVisibleItemsBoundsInScreen() const {
188 return shelf_view_
->GetVisibleItemsBoundsInScreen();
191 app_list::ApplicationDragAndDropHost
* Shelf::GetDragAndDropHostForAppList() {