This source file includes following definitions.
- GetAppListIcon
- observed_windows_
- AddAppWindow
- RemoveAppWindowForWindow
- SetActiveWindow
- IsOpen
- IsVisible
- Activate
- Close
- ActivateIndexedApp
- GetApplicationList
- ItemSelected
- GetTitle
- CreateContextMenu
- CreateApplicationMenu
- IsDraggable
- ShouldShowTooltip
- OnWindowPropertyChanged
- ShowAndActivateOrMinimize
- ActivateOrAdvanceToNextAppWindow
#include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h"
#include "apps/app_window.h"
#include "apps/ui/native_app_window.h"
#include "ash/shelf/shelf_model.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item.h"
#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_v2app.h"
#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
#include "chrome/browser/ui/ash/launcher/launcher_application_menu_item_model.h"
#include "chrome/browser/ui/ash/launcher/launcher_context_menu.h"
#include "chrome/browser/ui/ash/launcher/launcher_item_controller.h"
#include "content/public/browser/web_contents.h"
#include "skia/ext/image_operations.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/events/event.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/wm/core/window_animations.h"
using apps::AppWindow;
namespace {
const int kAppListIconSize = 24;
scoped_ptr<gfx::Image> GetAppListIcon(AppWindow* app_window) {
if (app_window->app_icon().IsEmpty())
return make_scoped_ptr(new gfx::Image());
SkBitmap bmp =
skia::ImageOperations::Resize(*app_window->app_icon().ToSkBitmap(),
skia::ImageOperations::RESIZE_BEST,
kAppListIconSize,
kAppListIconSize);
return make_scoped_ptr(
new gfx::Image(gfx::ImageSkia::CreateFrom1xBitmap(bmp)));
}
class AppWindowHasWindow {
public:
explicit AppWindowHasWindow(aura::Window* window) : window_(window) {}
bool operator()(AppWindow* app_window) const {
return app_window->GetNativeWindow() == window_;
}
private:
const aura::Window* window_;
};
}
AppWindowLauncherItemController::AppWindowLauncherItemController(
Type type,
const std::string& app_shelf_id,
const std::string& app_id,
ChromeLauncherController* controller)
: LauncherItemController(type, app_id, controller),
last_active_app_window_(NULL),
app_shelf_id_(app_shelf_id),
observed_windows_(this) {}
AppWindowLauncherItemController::~AppWindowLauncherItemController() {}
void AppWindowLauncherItemController::AddAppWindow(
AppWindow* app_window,
ash::ShelfItemStatus status) {
if (app_window->window_type_is_panel() && type() != TYPE_APP_PANEL)
LOG(ERROR) << "AppWindow of type Panel added to non-panel launcher item";
app_windows_.push_front(app_window);
observed_windows_.Add(app_window->GetNativeWindow());
}
void AppWindowLauncherItemController::RemoveAppWindowForWindow(
aura::Window* window) {
AppWindowList::iterator iter = std::find_if(
app_windows_.begin(), app_windows_.end(), AppWindowHasWindow(window));
if (iter != app_windows_.end()) {
if (*iter == last_active_app_window_)
last_active_app_window_ = NULL;
app_windows_.erase(iter);
}
observed_windows_.Remove(window);
}
void AppWindowLauncherItemController::SetActiveWindow(aura::Window* window) {
AppWindowList::iterator iter = std::find_if(
app_windows_.begin(), app_windows_.end(), AppWindowHasWindow(window));
if (iter != app_windows_.end())
last_active_app_window_ = *iter;
}
bool AppWindowLauncherItemController::IsOpen() const {
return !app_windows_.empty();
}
bool AppWindowLauncherItemController::IsVisible() const {
for (AppWindowList::const_iterator iter = app_windows_.begin();
iter != app_windows_.end();
++iter) {
if ((*iter)->GetNativeWindow()->IsVisible())
return true;
}
return false;
}
void AppWindowLauncherItemController::Launch(ash::LaunchSource source,
int event_flags) {
launcher_controller()->LaunchApp(app_id(), source, ui::EF_NONE);
}
bool AppWindowLauncherItemController::Activate(ash::LaunchSource source) {
DCHECK(!app_windows_.empty());
AppWindow* window_to_activate =
last_active_app_window_ ? last_active_app_window_ : app_windows_.back();
window_to_activate->GetBaseWindow()->Activate();
return false;
}
void AppWindowLauncherItemController::Close() {
AppWindowList windows_to_close = app_windows_;
for (AppWindowList::iterator iter = windows_to_close.begin();
iter != windows_to_close.end();
++iter) {
(*iter)->GetBaseWindow()->Close();
}
}
void AppWindowLauncherItemController::ActivateIndexedApp(size_t index) {
if (index >= app_windows_.size())
return;
AppWindowList::iterator it = app_windows_.begin();
std::advance(it, index);
ShowAndActivateOrMinimize(*it);
}
ChromeLauncherAppMenuItems AppWindowLauncherItemController::GetApplicationList(
int event_flags) {
ChromeLauncherAppMenuItems items;
items.push_back(new ChromeLauncherAppMenuItem(GetTitle(), NULL, false));
int index = 0;
for (AppWindowList::iterator iter = app_windows_.begin();
iter != app_windows_.end();
++iter) {
AppWindow* app_window = *iter;
scoped_ptr<gfx::Image> image(GetAppListIcon(app_window));
items.push_back(new ChromeLauncherAppMenuItemV2App(
app_window->GetTitle(),
image.get(),
app_id(),
launcher_controller(),
index,
index == 0 ));
++index;
}
return items.Pass();
}
bool AppWindowLauncherItemController::ItemSelected(const ui::Event& event) {
if (app_windows_.empty())
return false;
if (type() == TYPE_APP_PANEL) {
DCHECK(app_windows_.size() == 1);
AppWindow* panel = app_windows_.front();
aura::Window* panel_window = panel->GetNativeWindow();
if (ash::wm::GetWindowState(panel_window)->panel_attached() &&
ash::wm::MoveWindowToEventRoot(panel_window, event)) {
if (!panel->GetBaseWindow()->IsActive())
ShowAndActivateOrMinimize(panel);
} else {
ShowAndActivateOrMinimize(panel);
}
} else {
AppWindow* window_to_show = last_active_app_window_
? last_active_app_window_
: app_windows_.front();
if (app_windows_.size() >= 1 &&
window_to_show->GetBaseWindow()->IsActive() &&
event.type() == ui::ET_KEY_RELEASED) {
ActivateOrAdvanceToNextAppWindow(window_to_show);
} else {
ShowAndActivateOrMinimize(window_to_show);
}
}
return false;
}
base::string16 AppWindowLauncherItemController::GetTitle() {
if (type() == TYPE_APP_PANEL && !app_windows_.empty()) {
AppWindow* app_window = app_windows_.front();
if (app_window->web_contents()) {
base::string16 title = app_window->web_contents()->GetTitle();
if (!title.empty())
return title;
}
}
return GetAppTitle();
}
ui::MenuModel* AppWindowLauncherItemController::CreateContextMenu(
aura::Window* root_window) {
ash::ShelfItem item = *(launcher_controller()->model()->ItemByID(shelf_id()));
return new LauncherContextMenu(launcher_controller(), &item, root_window);
}
ash::ShelfMenuModel* AppWindowLauncherItemController::CreateApplicationMenu(
int event_flags) {
return new LauncherApplicationMenuItemModel(GetApplicationList(event_flags));
}
bool AppWindowLauncherItemController::IsDraggable() {
if (type() == TYPE_APP_PANEL)
return true;
return launcher_controller()->CanPin() ? true : false;
}
bool AppWindowLauncherItemController::ShouldShowTooltip() {
if (type() == TYPE_APP_PANEL && IsVisible())
return false;
return true;
}
void AppWindowLauncherItemController::OnWindowPropertyChanged(
aura::Window* window,
const void* key,
intptr_t old) {
if (key == aura::client::kDrawAttentionKey) {
ash::ShelfItemStatus status;
if (ash::wm::IsActiveWindow(window)) {
status = ash::STATUS_ACTIVE;
} else if (window->GetProperty(aura::client::kDrawAttentionKey)) {
status = ash::STATUS_ATTENTION;
} else {
status = ash::STATUS_RUNNING;
}
launcher_controller()->SetItemStatus(shelf_id(), status);
}
}
void AppWindowLauncherItemController::ShowAndActivateOrMinimize(
AppWindow* app_window) {
launcher_controller()->ActivateWindowOrMinimizeIfActive(
app_window->GetBaseWindow(), GetApplicationList(0).size() == 2);
}
void AppWindowLauncherItemController::ActivateOrAdvanceToNextAppWindow(
AppWindow* window_to_show) {
AppWindowList::iterator i(
std::find(app_windows_.begin(), app_windows_.end(), window_to_show));
if (i != app_windows_.end()) {
if (++i != app_windows_.end())
window_to_show = *i;
else
window_to_show = app_windows_.front();
}
if (window_to_show->GetBaseWindow()->IsActive()) {
AnimateWindow(window_to_show->GetNativeWindow(),
wm::WINDOW_ANIMATION_TYPE_BOUNCE);
} else {
ShowAndActivateOrMinimize(window_to_show);
}
}