| Index: ash/mus/shelf_delegate_mus.cc
|
| diff --git a/ash/mus/shelf_delegate_mus.cc b/ash/mus/shelf_delegate_mus.cc
|
| index 8bb11ad68fac4ad7108fce21c4fafa8d8b9d5ae1..fff6233af5a72cab81ff26ceea0d57fe4320ff17 100644
|
| --- a/ash/mus/shelf_delegate_mus.cc
|
| +++ b/ash/mus/shelf_delegate_mus.cc
|
| @@ -10,6 +10,7 @@
|
| #include "ash/shelf/shelf_item_delegate.h"
|
| #include "ash/shelf/shelf_item_delegate_manager.h"
|
| #include "ash/shelf/shelf_layout_manager.h"
|
| +#include "ash/shelf/shelf_menu_model.h"
|
| #include "ash/shelf/shelf_model.h"
|
| #include "ash/shelf/shelf_types.h"
|
| #include "ash/shelf/shelf_widget.h"
|
| @@ -37,38 +38,90 @@ namespace {
|
| // A ShelfItemDelegate used for pinned items and open user windows.
|
| class ShelfItemDelegateMus : public ShelfItemDelegate {
|
| public:
|
| - ShelfItemDelegateMus(uint32_t window_id,
|
| - const base::string16& title,
|
| - UserWindowController* user_window_controller)
|
| - : window_id_(window_id),
|
| - title_(title),
|
| - user_window_controller_(user_window_controller) {}
|
| + explicit ShelfItemDelegateMus(UserWindowController* user_window_controller)
|
| + : user_window_controller_(user_window_controller) {}
|
| ~ShelfItemDelegateMus() override {}
|
|
|
| - void UpdateTitle(const base::string16& new_title) { title_ = new_title; }
|
| + bool pinned() const { return pinned_; }
|
| + void set_pinned(bool pinned) { pinned_ = pinned; }
|
| +
|
| + void AddWindow(uint32_t id, const base::string16& title) {
|
| + DCHECK(!window_id_to_title_.count(id));
|
| + window_id_to_title_.insert(std::make_pair(id, title));
|
| + }
|
| + void RemoveWindow(uint32_t id) { window_id_to_title_.erase(id); }
|
| + void SetWindowTitle(uint32_t id, const base::string16& title) {
|
| + DCHECK(window_id_to_title_.count(id));
|
| + window_id_to_title_[id] = title;
|
| + }
|
| + const std::map<uint32_t, base::string16>& window_id_to_title() const {
|
| + return window_id_to_title_;
|
| + }
|
| +
|
| + const base::string16& title() { return title_; }
|
| + void set_title(const base::string16& title) { title_ = title; }
|
|
|
| private:
|
| + // This application menu model for ShelfItemDelegateMus lists open windows.
|
| + class ShelfMenuModelMus : public ShelfMenuModel,
|
| + public ui::SimpleMenuModel::Delegate {
|
| + public:
|
| + explicit ShelfMenuModelMus(ShelfItemDelegateMus* item_delegate)
|
| + : ShelfMenuModel(this), item_delegate_(item_delegate) {
|
| + AddSeparator(ui::SPACING_SEPARATOR);
|
| + AddItem(0, item_delegate_->GetTitle());
|
| + AddSeparator(ui::SPACING_SEPARATOR);
|
| + for (const auto& window : item_delegate_->window_id_to_title())
|
| + AddItem(window.first, window.second);
|
| + AddSeparator(ui::SPACING_SEPARATOR);
|
| + }
|
| + ~ShelfMenuModelMus() override {}
|
| +
|
| + // ShelfMenuModel:
|
| + bool IsCommandActive(int command_id) const override { return false; }
|
| +
|
| + // ui::SimpleMenuModel::Delegate:
|
| + bool IsCommandIdChecked(int command_id) const override { return false; }
|
| + bool IsCommandIdEnabled(int command_id) const override {
|
| + return command_id > 0;
|
| + }
|
| + bool GetAcceleratorForCommandId(int command_id,
|
| + ui::Accelerator* accelerator) override {
|
| + return false;
|
| + }
|
| + void ExecuteCommand(int command_id, int event_flags) override {
|
| + item_delegate_->user_window_controller_->FocusUserWindow(command_id);
|
| + }
|
| +
|
| + private:
|
| + ShelfItemDelegateMus* item_delegate_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ShelfMenuModelMus);
|
| + };
|
| +
|
| // ShelfItemDelegate:
|
| ShelfItemDelegate::PerformedAction ItemSelected(
|
| const ui::Event& event) override {
|
| - if (window_id_ != 0) {
|
| - user_window_controller_->FocusUserWindow(window_id_);
|
| + if (window_id_to_title_.size() == 1) {
|
| + user_window_controller_->FocusUserWindow(
|
| + window_id_to_title_.begin()->first);
|
| return kExistingWindowActivated;
|
| }
|
| - NOTIMPLEMENTED();
|
| return kNoAction;
|
| }
|
|
|
| - base::string16 GetTitle() override { return title_; }
|
| + base::string16 GetTitle() override {
|
| + return window_id_to_title_.empty() ? title_
|
| + : window_id_to_title_.begin()->second;
|
| + }
|
|
|
| bool CanPin() const override {
|
| NOTIMPLEMENTED();
|
| - return false;
|
| + return true;
|
| }
|
|
|
| ShelfMenuModel* CreateApplicationMenu(int event_flags) override {
|
| - NOTIMPLEMENTED();
|
| - return nullptr;
|
| + return new ShelfMenuModelMus(this);
|
| }
|
|
|
| bool IsDraggable() override {
|
| @@ -80,14 +133,20 @@ class ShelfItemDelegateMus : public ShelfItemDelegate {
|
|
|
| void Close() override { NOTIMPLEMENTED(); }
|
|
|
| - // TODO(msw): Support multiple open windows per button.
|
| - uint32_t window_id_;
|
| + bool pinned_ = false;
|
| + std::map<uint32_t, base::string16> window_id_to_title_;
|
| base::string16 title_;
|
| UserWindowController* user_window_controller_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ShelfItemDelegateMus);
|
| };
|
|
|
| +ShelfItemDelegateMus* GetShelfItemDelegate(ShelfID shelf_id) {
|
| + return static_cast<ShelfItemDelegateMus*>(
|
| + Shell::GetInstance()->shelf_item_delegate_manager()->GetShelfItemDelegate(
|
| + shelf_id));
|
| +}
|
| +
|
| // Returns an icon image from an SkBitmap, or the default shelf icon
|
| // image if the bitmap is empty. Assumes the bitmap is a 1x icon.
|
| // TODO(jamescook): Support other scale factors.
|
| @@ -210,31 +269,43 @@ void ShelfDelegateMus::SetAutoHideBehavior(
|
| Shell::GetPrimaryRootWindow());
|
| }
|
|
|
| -void ShelfDelegateMus::AddItem(
|
| +void ShelfDelegateMus::PinItem(
|
| mash::shelf::mojom::ShelfItemPtr item,
|
| mash::shelf::mojom::ShelfItemDelegateAssociatedPtrInfo delegate) {
|
| + std::string app_id(item->app_id.To<std::string>());
|
| + if (app_id_to_shelf_id_.count(app_id)) {
|
| + ShelfID shelf_id = app_id_to_shelf_id_[app_id];
|
| + ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id);
|
| + item_delegate->set_pinned(true);
|
| + return;
|
| + }
|
| +
|
| + ShelfID shelf_id = model_->next_id();
|
| + app_id_to_shelf_id_.insert(std::make_pair(app_id, shelf_id));
|
| +
|
| ShelfItem shelf_item;
|
| shelf_item.type = TYPE_APP_SHORTCUT;
|
| shelf_item.status = STATUS_CLOSED;
|
| shelf_item.image = GetShelfIconFromBitmap(item->image.To<SkBitmap>());
|
| -
|
| - std::string item_id(item->id.To<std::string>());
|
| - if (app_id_to_shelf_id_.count(item_id))
|
| - return;
|
| - ShelfID shelf_id = model_->next_id();
|
| - app_id_to_shelf_id_.insert(std::make_pair(item_id, shelf_id));
|
| model_->Add(shelf_item);
|
|
|
| - std::unique_ptr<ShelfItemDelegateMus> item_delegate(new ShelfItemDelegateMus(
|
| - 0, item->title.To<base::string16>(), user_window_controller_.get()));
|
| + std::unique_ptr<ShelfItemDelegateMus> item_delegate(
|
| + new ShelfItemDelegateMus(user_window_controller_.get()));
|
| + item_delegate->set_pinned(true);
|
| + item_delegate->set_title(item->app_title.To<base::string16>());
|
| Shell::GetInstance()->shelf_item_delegate_manager()->SetShelfItemDelegate(
|
| shelf_id, std::move(item_delegate));
|
| }
|
|
|
| -void ShelfDelegateMus::RemoveItem(const mojo::String& id) {
|
| - std::string item_id(id.To<std::string>());
|
| - DCHECK(app_id_to_shelf_id_.count(item_id));
|
| - model_->RemoveItemAt(model_->ItemIndexByID(app_id_to_shelf_id_[item_id]));
|
| +void ShelfDelegateMus::UnpinItem(const mojo::String& app_id) {
|
| + if (!app_id_to_shelf_id_.count(app_id.To<std::string>()))
|
| + return;
|
| + ShelfID shelf_id = app_id_to_shelf_id_[app_id.To<std::string>()];
|
| + ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id);
|
| + DCHECK(item_delegate->pinned());
|
| + item_delegate->set_pinned(false);
|
| + if (item_delegate->window_id_to_title().empty())
|
| + model_->RemoveItemAt(model_->ItemIndexByID(shelf_id));
|
| }
|
|
|
| void ShelfDelegateMus::OnUserWindowObserverAdded(
|
| @@ -245,27 +316,47 @@ void ShelfDelegateMus::OnUserWindowObserverAdded(
|
|
|
| void ShelfDelegateMus::OnUserWindowAdded(
|
| mash::wm::mojom::UserWindowPtr user_window) {
|
| - ShelfItem item;
|
| - item.type = TYPE_PLATFORM_APP;
|
| - item.status = user_window->window_has_focus ? STATUS_ACTIVE : STATUS_RUNNING;
|
| - item.image = GetShelfIconFromSerializedBitmap(user_window->window_app_icon);
|
| + DCHECK(!window_id_to_shelf_id_.count(user_window->window_id));
|
| +
|
| + std::string app_id(user_window->window_app_id.To<std::string>());
|
| + if (app_id_to_shelf_id_.count(app_id)) {
|
| + ShelfID shelf_id = app_id_to_shelf_id_[app_id];
|
| + window_id_to_shelf_id_.insert(
|
| + std::make_pair(user_window->window_id, shelf_id));
|
| +
|
| + ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id);
|
| + item_delegate->AddWindow(user_window->window_id,
|
| + user_window->window_title.To<base::string16>());
|
| + return;
|
| + }
|
|
|
| ShelfID shelf_id = model_->next_id();
|
| window_id_to_shelf_id_.insert(
|
| std::make_pair(user_window->window_id, shelf_id));
|
| + app_id_to_shelf_id_.insert(std::make_pair(app_id, shelf_id));
|
| +
|
| + ShelfItem item;
|
| + item.type = TYPE_PLATFORM_APP;
|
| + item.status = user_window->window_has_focus ? STATUS_ACTIVE : STATUS_RUNNING;
|
| + item.image = GetShelfIconFromSerializedBitmap(user_window->window_app_icon);
|
| model_->Add(item);
|
|
|
| - std::unique_ptr<ShelfItemDelegate> item_delegate(new ShelfItemDelegateMus(
|
| - user_window->window_id, user_window->window_title.To<base::string16>(),
|
| - user_window_controller_.get()));
|
| + std::unique_ptr<ShelfItemDelegateMus> item_delegate(
|
| + new ShelfItemDelegateMus(user_window_controller_.get()));
|
| + item_delegate->AddWindow(user_window->window_id,
|
| + user_window->window_title.To<base::string16>());
|
| Shell::GetInstance()->shelf_item_delegate_manager()->SetShelfItemDelegate(
|
| shelf_id, std::move(item_delegate));
|
| }
|
|
|
| void ShelfDelegateMus::OnUserWindowRemoved(uint32_t window_id) {
|
| DCHECK(window_id_to_shelf_id_.count(window_id));
|
| - model_->RemoveItemAt(
|
| - model_->ItemIndexByID(window_id_to_shelf_id_[window_id]));
|
| + ShelfID shelf_id = window_id_to_shelf_id_[window_id];
|
| + ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id);
|
| + item_delegate->RemoveWindow(window_id);
|
| + window_id_to_shelf_id_.erase(window_id);
|
| + if (item_delegate->window_id_to_title().empty() && !item_delegate->pinned())
|
| + model_->RemoveItemAt(model_->ItemIndexByID(shelf_id));
|
| }
|
|
|
| void ShelfDelegateMus::OnUserWindowTitleChanged(
|
| @@ -273,12 +364,8 @@ void ShelfDelegateMus::OnUserWindowTitleChanged(
|
| const mojo::String& window_title) {
|
| DCHECK(window_id_to_shelf_id_.count(window_id));
|
| ShelfID shelf_id = window_id_to_shelf_id_[window_id];
|
| - ShelfItemDelegateManager* manager =
|
| - Shell::GetInstance()->shelf_item_delegate_manager();
|
| - ShelfItemDelegate* delegate = manager->GetShelfItemDelegate(shelf_id);
|
| - DCHECK(delegate);
|
| - static_cast<ShelfItemDelegateMus*>(delegate)->UpdateTitle(
|
| - window_title.To<base::string16>());
|
| + ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id);
|
| + item_delegate->SetWindowTitle(window_id, window_title.To<base::string16>());
|
|
|
| // There's nothing in the ShelfItem that needs to be updated. But we still
|
| // need to update the ShelfModel so that the observers can pick up any
|
|
|