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/client/activation_client.h"
28 #include "ui/aura/root_window.h"
29 #include "ui/aura/window.h"
30 #include "ui/aura/window_observer.h"
31 #include "ui/base/resource/resource_bundle.h"
32 #include "ui/compositor/layer.h"
33 #include "ui/gfx/canvas.h"
34 #include "ui/gfx/image/image.h"
35 #include "ui/gfx/image/image_skia_operations.h"
36 #include "ui/gfx/skbitmap_operations.h"
37 #include "ui/views/accessible_pane_view.h"
38 #include "ui/views/widget/widget.h"
39 #include "ui/views/widget/widget_delegate.h"
43 const char Shelf::kNativeViewName
[] = "ShelfView";
45 Shelf::Shelf(ShelfModel
* shelf_model
,
46 ShelfDelegate
* shelf_delegate
,
47 ShelfWidget
* shelf_widget
)
49 alignment_(shelf_widget
->GetAlignment()),
50 delegate_(shelf_delegate
),
51 shelf_widget_(shelf_widget
) {
52 shelf_view_
= new internal::ShelfView(
53 shelf_model
, delegate_
, shelf_widget_
->shelf_layout_manager());
55 shelf_widget_
->GetContentsView()->AddChildView(shelf_view_
);
56 shelf_widget_
->GetNativeView()->SetName(kNativeViewName
);
57 delegate_
->OnShelfCreated(this);
61 delegate_
->OnShelfDestroyed(this);
65 Shelf
* Shelf::ForPrimaryDisplay() {
66 ShelfWidget
* shelf_widget
= internal::RootWindowController::ForShelf(
67 Shell::GetPrimaryRootWindow())->shelf();
68 return shelf_widget
? shelf_widget
->shelf() : NULL
;
72 Shelf
* Shelf::ForWindow(aura::Window
* window
) {
73 ShelfWidget
* shelf_widget
=
74 internal::RootWindowController::ForShelf(window
)->shelf();
75 return shelf_widget
? shelf_widget
->shelf() : NULL
;
78 void Shelf::SetAlignment(ShelfAlignment alignment
) {
79 alignment_
= alignment
;
80 shelf_view_
->OnShelfAlignmentChanged();
81 // ShelfLayoutManager will resize the shelf.
84 gfx::Rect
Shelf::GetScreenBoundsOfItemIconForWindow(aura::Window
* window
) {
85 ShelfID id
= GetShelfIDForWindow(window
);
86 gfx::Rect
bounds(shelf_view_
->GetIdealBoundsOfItemIcon(id
));
87 gfx::Point screen_origin
;
88 views::View::ConvertPointToScreen(shelf_view_
, &screen_origin
);
89 return gfx::Rect(screen_origin
.x() + bounds
.x(),
90 screen_origin
.y() + bounds
.y(),
95 void Shelf::UpdateIconPositionForWindow(aura::Window
* window
) {
96 shelf_view_
->UpdatePanelIconPosition(
97 GetShelfIDForWindow(window
),
98 ScreenUtil::ConvertRectFromScreen(
99 shelf_widget()->GetNativeView(),
100 window
->GetBoundsInScreen()).CenterPoint());
103 void Shelf::ActivateShelfItem(int index
) {
104 // We pass in a keyboard event which will then trigger a switch to the
105 // next item if the current one is already active.
106 ui::KeyEvent
event(ui::ET_KEY_RELEASED
,
107 ui::VKEY_UNKNOWN
, // The actual key gets ignored.
111 const ShelfItem
& item
= shelf_view_
->model()->items()[index
];
112 ShelfItemDelegate
* item_delegate
=
113 Shell::GetInstance()->shelf_item_delegate_manager()->GetShelfItemDelegate(
115 item_delegate
->ItemSelected(event
);
118 void Shelf::CycleWindowLinear(CycleDirection direction
) {
119 int item_index
= GetNextActivatedItemIndex(
120 *(shelf_view_
->model()), direction
);
122 ActivateShelfItem(item_index
);
125 void Shelf::AddIconObserver(ShelfIconObserver
* observer
) {
126 shelf_view_
->AddIconObserver(observer
);
129 void Shelf::RemoveIconObserver(ShelfIconObserver
* observer
) {
130 shelf_view_
->RemoveIconObserver(observer
);
133 bool Shelf::IsShowingMenu() const {
134 return shelf_view_
->IsShowingMenu();
137 bool Shelf::IsShowingOverflowBubble() const {
138 return shelf_view_
->IsShowingOverflowBubble();
141 void Shelf::SetVisible(bool visible
) const {
142 shelf_view_
->SetVisible(visible
);
145 bool Shelf::IsVisible() const {
146 return shelf_view_
->visible();
149 void Shelf::SchedulePaint() {
150 shelf_view_
->SchedulePaintForAllButtons();
153 views::View
* Shelf::GetAppListButtonView() const {
154 return shelf_view_
->GetAppListButtonView();
157 void Shelf::LaunchAppIndexAt(int item_index
) {
158 ShelfModel
* shelf_model
= shelf_view_
->model();
159 const ShelfItems
& items
= shelf_model
->items();
160 int item_count
= shelf_model
->item_count();
161 int indexes_left
= item_index
>= 0 ? item_index
: item_count
;
162 int found_index
= -1;
164 // Iterating until we have hit the index we are interested in which
165 // is true once indexes_left becomes negative.
166 for (int i
= 0; i
< item_count
&& indexes_left
>= 0; i
++) {
167 if (items
[i
].type
!= TYPE_APP_LIST
) {
173 // There are two ways how found_index can be valid: a.) the nth item was
174 // found (which is true when indexes_left is -1) or b.) the last item was
175 // requested (which is true when index was passed in as a negative number).
176 if (found_index
>= 0 && (indexes_left
== -1 || item_index
< 0)) {
177 // Then set this one as active (or advance to the next item of its kind).
178 ActivateShelfItem(found_index
);
182 void Shelf::SetShelfViewBounds(gfx::Rect bounds
) {
183 shelf_view_
->SetBoundsRect(bounds
);
186 gfx::Rect
Shelf::GetShelfViewBounds() const {
187 return shelf_view_
->bounds();
190 gfx::Rect
Shelf::GetVisibleItemsBoundsInScreen() const {
191 return shelf_view_
->GetVisibleItemsBoundsInScreen();
194 app_list::ApplicationDragAndDropHost
* Shelf::GetDragAndDropHostForAppList() {