1 // Copyright (c) 2012 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. 4 5 #include "ash/launcher/launcher.h" 6 7 #include <algorithm> 8 #include <cmath> 9 10 #include "ash/focus_cycler.h" 11 #include "ash/launcher/launcher_delegate.h" 12 #include "ash/launcher/launcher_model.h" 13 #include "ash/launcher/launcher_navigator.h" 14 #include "ash/launcher/launcher_view.h" 15 #include "ash/root_window_controller.h" 16 #include "ash/screen_ash.h" 17 #include "ash/shelf/shelf_layout_manager.h" 18 #include "ash/shelf/shelf_widget.h" 19 #include "ash/shell.h" 20 #include "ash/shell_delegate.h" 21 #include "ash/shell_window_ids.h" 22 #include "ash/wm/property_util.h" 23 #include "ash/wm/window_properties.h" 24 #include "grit/ash_resources.h" 25 #include "ui/aura/client/activation_client.h" 26 #include "ui/aura/root_window.h" 27 #include "ui/aura/window.h" 28 #include "ui/aura/window_observer.h" 29 #include "ui/base/resource/resource_bundle.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 39 namespace ash { 40 41 const char Launcher::kNativeViewName[] = "LauncherView"; 42 43 Launcher::Launcher(LauncherModel* launcher_model, 44 LauncherDelegate* launcher_delegate, 45 ShelfWidget* shelf_widget) 46 : launcher_view_(NULL), 47 alignment_(shelf_widget->GetAlignment()), 48 delegate_(launcher_delegate), 49 shelf_widget_(shelf_widget) { 50 launcher_view_ = new internal::LauncherView( 51 launcher_model, delegate_, shelf_widget_->shelf_layout_manager()); 52 launcher_view_->Init(); 53 shelf_widget_->GetContentsView()->AddChildView(launcher_view_); 54 shelf_widget_->GetNativeView()->SetName(kNativeViewName); 55 delegate_->OnLauncherCreated(this); 56 } 57 58 Launcher::~Launcher() { 59 delegate_->OnLauncherDestroyed(this); 60 } 61 62 // static 63 Launcher* Launcher::ForPrimaryDisplay() { 64 ShelfWidget* shelf_widget = internal::RootWindowController::ForLauncher( 65 Shell::GetPrimaryRootWindow())->shelf(); 66 return shelf_widget ? shelf_widget->launcher() : NULL; 67 } 68 69 // static 70 Launcher* Launcher::ForWindow(aura::Window* window) { 71 ShelfWidget* shelf_widget = 72 internal::RootWindowController::ForLauncher(window)->shelf(); 73 return shelf_widget ? shelf_widget->launcher() : NULL; 74 } 75 76 void Launcher::SetAlignment(ShelfAlignment alignment) { 77 alignment_ = alignment; 78 launcher_view_->OnShelfAlignmentChanged(); 79 // ShelfLayoutManager will resize the launcher. 80 } 81 82 gfx::Rect Launcher::GetScreenBoundsOfItemIconForWindow(aura::Window* window) { 83 LauncherID id = delegate_->GetIDByWindow(window); 84 gfx::Rect bounds(launcher_view_->GetIdealBoundsOfItemIcon(id)); 85 gfx::Point screen_origin; 86 views::View::ConvertPointToScreen(launcher_view_, &screen_origin); 87 return gfx::Rect(screen_origin.x() + bounds.x(), 88 screen_origin.y() + bounds.y(), 89 bounds.width(), 90 bounds.height()); 91 } 92 93 void Launcher::UpdateIconPositionForWindow(aura::Window* window) { 94 launcher_view_->UpdatePanelIconPosition( 95 delegate_->GetIDByWindow(window), 96 ash::ScreenAsh::ConvertRectFromScreen( 97 shelf_widget()->GetNativeView(), 98 window->GetBoundsInScreen()).CenterPoint()); 99 } 100 101 void Launcher::ActivateLauncherItem(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. 106 ui::EF_NONE, 107 false); 108 109 const ash::LauncherItems& items = 110 launcher_view_->model()->items(); 111 delegate_->ItemSelected(items[index], event); 112 } 113 114 void Launcher::CycleWindowLinear(CycleDirection direction) { 115 int item_index = GetNextActivatedItemIndex( 116 *(launcher_view_->model()), direction); 117 if (item_index >= 0) 118 ActivateLauncherItem(item_index); 119 } 120 121 void Launcher::AddIconObserver(LauncherIconObserver* observer) { 122 launcher_view_->AddIconObserver(observer); 123 } 124 125 void Launcher::RemoveIconObserver(LauncherIconObserver* observer) { 126 launcher_view_->RemoveIconObserver(observer); 127 } 128 129 bool Launcher::IsShowingMenu() const { 130 return launcher_view_->IsShowingMenu(); 131 } 132 133 bool Launcher::IsShowingOverflowBubble() const { 134 return launcher_view_->IsShowingOverflowBubble(); 135 } 136 137 void Launcher::SetVisible(bool visible) const { 138 launcher_view_->SetVisible(visible); 139 } 140 141 bool Launcher::IsVisible() const { 142 return launcher_view_->visible(); 143 } 144 145 void Launcher::SchedulePaint() { 146 launcher_view_->SchedulePaintForAllButtons(); 147 } 148 149 views::View* Launcher::GetAppListButtonView() const { 150 return launcher_view_->GetAppListButtonView(); 151 } 152 153 void Launcher::LaunchAppIndexAt(int item_index) { 154 LauncherModel* launcher_model = launcher_view_->model(); 155 const LauncherItems& items = launcher_model->items(); 156 int item_count = launcher_model->item_count(); 157 int indexes_left = item_index >= 0 ? item_index : item_count; 158 int found_index = -1; 159 160 // Iterating until we have hit the index we are interested in which 161 // is true once indexes_left becomes negative. 162 for (int i = 0; i < item_count && indexes_left >= 0; i++) { 163 if (items[i].type != TYPE_APP_LIST) { 164 found_index = i; 165 indexes_left--; 166 } 167 } 168 169 // There are two ways how found_index can be valid: a.) the nth item was 170 // found (which is true when indexes_left is -1) or b.) the last item was 171 // requested (which is true when index was passed in as a negative number). 172 if (found_index >= 0 && (indexes_left == -1 || item_index < 0) && 173 (delegate_->IsPerAppLauncher() || 174 (items[found_index].status == ash::STATUS_RUNNING || 175 items[found_index].status == ash::STATUS_CLOSED))) { 176 // Then set this one as active (or advance to the next item of its kind). 177 ActivateLauncherItem(found_index); 178 } 179 } 180 181 internal::LauncherView* Launcher::GetLauncherViewForTest() { 182 return launcher_view_; 183 } 184 185 void Launcher::SetLauncherViewBounds(gfx::Rect bounds) { 186 launcher_view_->SetBoundsRect(bounds); 187 } 188 189 gfx::Rect Launcher::GetLauncherViewBounds() const { 190 return launcher_view_->bounds(); 191 } 192 193 app_list::ApplicationDragAndDropHost* Launcher::GetDragAndDropHostForAppList() { 194 return launcher_view_; 195 } 196 197 } // namespace ash 198