OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/mus/shelf_delegate_mus.h" | 5 #include "ash/mus/shelf_delegate_mus.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "ash/shelf/shelf.h" | 9 #include "ash/shelf/shelf.h" |
10 #include "ash/shelf/shelf_item_delegate.h" | 10 #include "ash/shelf/shelf_item_delegate.h" |
11 #include "ash/shelf/shelf_item_delegate_manager.h" | 11 #include "ash/shelf/shelf_item_delegate_manager.h" |
12 #include "ash/shelf/shelf_layout_manager.h" | 12 #include "ash/shelf/shelf_layout_manager.h" |
| 13 #include "ash/shelf/shelf_menu_model.h" |
13 #include "ash/shelf/shelf_model.h" | 14 #include "ash/shelf/shelf_model.h" |
14 #include "ash/shelf/shelf_types.h" | 15 #include "ash/shelf/shelf_types.h" |
15 #include "ash/shelf/shelf_widget.h" | 16 #include "ash/shelf/shelf_widget.h" |
16 #include "ash/shell.h" | 17 #include "ash/shell.h" |
17 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
18 #include "components/mus/public/cpp/property_type_converters.h" | 19 #include "components/mus/public/cpp/property_type_converters.h" |
19 #include "components/mus/public/cpp/window.h" | 20 #include "components/mus/public/cpp/window.h" |
20 #include "components/mus/public/cpp/window_property.h" | 21 #include "components/mus/public/cpp/window_property.h" |
21 #include "mojo/common/common_type_converters.h" | 22 #include "mojo/common/common_type_converters.h" |
22 #include "services/shell/public/cpp/connector.h" | 23 #include "services/shell/public/cpp/connector.h" |
23 #include "skia/public/type_converters.h" | 24 #include "skia/public/type_converters.h" |
24 #include "ui/aura/mus/mus_util.h" | 25 #include "ui/aura/mus/mus_util.h" |
25 #include "ui/base/resource/resource_bundle.h" | 26 #include "ui/base/resource/resource_bundle.h" |
26 #include "ui/gfx/image/image_skia.h" | 27 #include "ui/gfx/image/image_skia.h" |
27 #include "ui/resources/grit/ui_resources.h" | 28 #include "ui/resources/grit/ui_resources.h" |
28 #include "ui/views/mus/window_manager_connection.h" | 29 #include "ui/views/mus/window_manager_connection.h" |
29 | 30 |
30 using mash::wm::mojom::UserWindowController; | 31 using mash::wm::mojom::UserWindowController; |
31 | 32 |
32 namespace ash { | 33 namespace ash { |
33 namespace sysui { | 34 namespace sysui { |
34 | 35 |
35 namespace { | 36 namespace { |
36 | 37 |
37 // A ShelfItemDelegate used for pinned items and open user windows. | 38 // A ShelfItemDelegate used for pinned items and open user windows. |
38 class ShelfItemDelegateMus : public ShelfItemDelegate { | 39 class ShelfItemDelegateMus : public ShelfItemDelegate { |
39 public: | 40 public: |
40 ShelfItemDelegateMus(uint32_t window_id, | 41 explicit ShelfItemDelegateMus(UserWindowController* user_window_controller) |
41 const base::string16& title, | 42 : user_window_controller_(user_window_controller) {} |
42 UserWindowController* user_window_controller) | |
43 : window_id_(window_id), | |
44 title_(title), | |
45 user_window_controller_(user_window_controller) {} | |
46 ~ShelfItemDelegateMus() override {} | 43 ~ShelfItemDelegateMus() override {} |
47 | 44 |
48 void UpdateTitle(const base::string16& new_title) { title_ = new_title; } | 45 bool pinned() const { return pinned_; } |
| 46 void set_pinned(bool pinned) { pinned_ = pinned; } |
| 47 |
| 48 void AddWindow(uint32_t id, const base::string16& title) { |
| 49 DCHECK(!window_id_to_title_.count(id)); |
| 50 window_id_to_title_.insert(std::make_pair(id, title)); |
| 51 } |
| 52 void RemoveWindow(uint32_t id) { window_id_to_title_.erase(id); } |
| 53 void SetWindowTitle(uint32_t id, const base::string16& title) { |
| 54 DCHECK(window_id_to_title_.count(id)); |
| 55 window_id_to_title_[id] = title; |
| 56 } |
| 57 const std::map<uint32_t, base::string16>& window_id_to_title() const { |
| 58 return window_id_to_title_; |
| 59 } |
| 60 |
| 61 const base::string16& title() { return title_; } |
| 62 void set_title(const base::string16& title) { title_ = title; } |
49 | 63 |
50 private: | 64 private: |
| 65 // This application menu model for ShelfItemDelegateMus lists open windows. |
| 66 class ShelfMenuModelMus : public ShelfMenuModel, |
| 67 public ui::SimpleMenuModel::Delegate { |
| 68 public: |
| 69 explicit ShelfMenuModelMus(ShelfItemDelegateMus* item_delegate) |
| 70 : ShelfMenuModel(this), item_delegate_(item_delegate) { |
| 71 AddSeparator(ui::SPACING_SEPARATOR); |
| 72 AddItem(0, item_delegate_->GetTitle()); |
| 73 AddSeparator(ui::SPACING_SEPARATOR); |
| 74 for (const auto& window : item_delegate_->window_id_to_title()) |
| 75 AddItem(window.first, window.second); |
| 76 AddSeparator(ui::SPACING_SEPARATOR); |
| 77 } |
| 78 ~ShelfMenuModelMus() override {} |
| 79 |
| 80 // ShelfMenuModel: |
| 81 bool IsCommandActive(int command_id) const override { return false; } |
| 82 |
| 83 // ui::SimpleMenuModel::Delegate: |
| 84 bool IsCommandIdChecked(int command_id) const override { return false; } |
| 85 bool IsCommandIdEnabled(int command_id) const override { |
| 86 return command_id > 0; |
| 87 } |
| 88 bool GetAcceleratorForCommandId(int command_id, |
| 89 ui::Accelerator* accelerator) override { |
| 90 return false; |
| 91 } |
| 92 void ExecuteCommand(int command_id, int event_flags) override { |
| 93 item_delegate_->user_window_controller_->FocusUserWindow(command_id); |
| 94 } |
| 95 |
| 96 private: |
| 97 ShelfItemDelegateMus* item_delegate_; |
| 98 |
| 99 DISALLOW_COPY_AND_ASSIGN(ShelfMenuModelMus); |
| 100 }; |
| 101 |
51 // ShelfItemDelegate: | 102 // ShelfItemDelegate: |
52 ShelfItemDelegate::PerformedAction ItemSelected( | 103 ShelfItemDelegate::PerformedAction ItemSelected( |
53 const ui::Event& event) override { | 104 const ui::Event& event) override { |
54 if (window_id_ != 0) { | 105 if (window_id_to_title_.size() == 1) { |
55 user_window_controller_->FocusUserWindow(window_id_); | 106 user_window_controller_->FocusUserWindow( |
| 107 window_id_to_title_.begin()->first); |
56 return kExistingWindowActivated; | 108 return kExistingWindowActivated; |
57 } | 109 } |
58 NOTIMPLEMENTED(); | |
59 return kNoAction; | 110 return kNoAction; |
60 } | 111 } |
61 | 112 |
62 base::string16 GetTitle() override { return title_; } | 113 base::string16 GetTitle() override { |
| 114 return window_id_to_title_.empty() ? title_ |
| 115 : window_id_to_title_.begin()->second; |
| 116 } |
63 | 117 |
64 bool CanPin() const override { | 118 bool CanPin() const override { |
65 NOTIMPLEMENTED(); | 119 NOTIMPLEMENTED(); |
66 return false; | 120 return true; |
67 } | 121 } |
68 | 122 |
69 ShelfMenuModel* CreateApplicationMenu(int event_flags) override { | 123 ShelfMenuModel* CreateApplicationMenu(int event_flags) override { |
70 NOTIMPLEMENTED(); | 124 return new ShelfMenuModelMus(this); |
71 return nullptr; | |
72 } | 125 } |
73 | 126 |
74 bool IsDraggable() override { | 127 bool IsDraggable() override { |
75 NOTIMPLEMENTED(); | 128 NOTIMPLEMENTED(); |
76 return false; | 129 return false; |
77 } | 130 } |
78 | 131 |
79 bool ShouldShowTooltip() override { return true; } | 132 bool ShouldShowTooltip() override { return true; } |
80 | 133 |
81 void Close() override { NOTIMPLEMENTED(); } | 134 void Close() override { NOTIMPLEMENTED(); } |
82 | 135 |
83 // TODO(msw): Support multiple open windows per button. | 136 bool pinned_ = false; |
84 uint32_t window_id_; | 137 std::map<uint32_t, base::string16> window_id_to_title_; |
85 base::string16 title_; | 138 base::string16 title_; |
86 UserWindowController* user_window_controller_; | 139 UserWindowController* user_window_controller_; |
87 | 140 |
88 DISALLOW_COPY_AND_ASSIGN(ShelfItemDelegateMus); | 141 DISALLOW_COPY_AND_ASSIGN(ShelfItemDelegateMus); |
89 }; | 142 }; |
90 | 143 |
| 144 ShelfItemDelegateMus* GetShelfItemDelegate(ShelfID shelf_id) { |
| 145 return static_cast<ShelfItemDelegateMus*>( |
| 146 Shell::GetInstance()->shelf_item_delegate_manager()->GetShelfItemDelegate( |
| 147 shelf_id)); |
| 148 } |
| 149 |
91 // Returns an icon image from an SkBitmap, or the default shelf icon | 150 // Returns an icon image from an SkBitmap, or the default shelf icon |
92 // image if the bitmap is empty. Assumes the bitmap is a 1x icon. | 151 // image if the bitmap is empty. Assumes the bitmap is a 1x icon. |
93 // TODO(jamescook): Support other scale factors. | 152 // TODO(jamescook): Support other scale factors. |
94 gfx::ImageSkia GetShelfIconFromBitmap(const SkBitmap& bitmap) { | 153 gfx::ImageSkia GetShelfIconFromBitmap(const SkBitmap& bitmap) { |
95 gfx::ImageSkia icon_image; | 154 gfx::ImageSkia icon_image; |
96 if (!bitmap.isNull()) { | 155 if (!bitmap.isNull()) { |
97 icon_image = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); | 156 icon_image = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); |
98 } else { | 157 } else { |
99 // Use default icon. | 158 // Use default icon. |
100 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 159 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 Shell::GetInstance()->SetShelfAlignment(value, Shell::GetPrimaryRootWindow()); | 262 Shell::GetInstance()->SetShelfAlignment(value, Shell::GetPrimaryRootWindow()); |
204 } | 263 } |
205 | 264 |
206 void ShelfDelegateMus::SetAutoHideBehavior( | 265 void ShelfDelegateMus::SetAutoHideBehavior( |
207 mash::shelf::mojom::AutoHideBehavior auto_hide) { | 266 mash::shelf::mojom::AutoHideBehavior auto_hide) { |
208 ShelfAutoHideBehavior value = static_cast<ShelfAutoHideBehavior>(auto_hide); | 267 ShelfAutoHideBehavior value = static_cast<ShelfAutoHideBehavior>(auto_hide); |
209 Shell::GetInstance()->SetShelfAutoHideBehavior(value, | 268 Shell::GetInstance()->SetShelfAutoHideBehavior(value, |
210 Shell::GetPrimaryRootWindow()); | 269 Shell::GetPrimaryRootWindow()); |
211 } | 270 } |
212 | 271 |
213 void ShelfDelegateMus::AddItem( | 272 void ShelfDelegateMus::PinItem( |
214 mash::shelf::mojom::ShelfItemPtr item, | 273 mash::shelf::mojom::ShelfItemPtr item, |
215 mash::shelf::mojom::ShelfItemDelegateAssociatedPtrInfo delegate) { | 274 mash::shelf::mojom::ShelfItemDelegateAssociatedPtrInfo delegate) { |
| 275 std::string app_id(item->app_id.To<std::string>()); |
| 276 if (app_id_to_shelf_id_.count(app_id)) { |
| 277 ShelfID shelf_id = app_id_to_shelf_id_[app_id]; |
| 278 ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id); |
| 279 item_delegate->set_pinned(true); |
| 280 return; |
| 281 } |
| 282 |
| 283 ShelfID shelf_id = model_->next_id(); |
| 284 app_id_to_shelf_id_.insert(std::make_pair(app_id, shelf_id)); |
| 285 |
216 ShelfItem shelf_item; | 286 ShelfItem shelf_item; |
217 shelf_item.type = TYPE_APP_SHORTCUT; | 287 shelf_item.type = TYPE_APP_SHORTCUT; |
218 shelf_item.status = STATUS_CLOSED; | 288 shelf_item.status = STATUS_CLOSED; |
219 shelf_item.image = GetShelfIconFromBitmap(item->image.To<SkBitmap>()); | 289 shelf_item.image = GetShelfIconFromBitmap(item->image.To<SkBitmap>()); |
220 | |
221 std::string item_id(item->id.To<std::string>()); | |
222 if (app_id_to_shelf_id_.count(item_id)) | |
223 return; | |
224 ShelfID shelf_id = model_->next_id(); | |
225 app_id_to_shelf_id_.insert(std::make_pair(item_id, shelf_id)); | |
226 model_->Add(shelf_item); | 290 model_->Add(shelf_item); |
227 | 291 |
228 std::unique_ptr<ShelfItemDelegateMus> item_delegate(new ShelfItemDelegateMus( | 292 std::unique_ptr<ShelfItemDelegateMus> item_delegate( |
229 0, item->title.To<base::string16>(), user_window_controller_.get())); | 293 new ShelfItemDelegateMus(user_window_controller_.get())); |
| 294 item_delegate->set_pinned(true); |
| 295 item_delegate->set_title(item->app_title.To<base::string16>()); |
230 Shell::GetInstance()->shelf_item_delegate_manager()->SetShelfItemDelegate( | 296 Shell::GetInstance()->shelf_item_delegate_manager()->SetShelfItemDelegate( |
231 shelf_id, std::move(item_delegate)); | 297 shelf_id, std::move(item_delegate)); |
232 } | 298 } |
233 | 299 |
234 void ShelfDelegateMus::RemoveItem(const mojo::String& id) { | 300 void ShelfDelegateMus::UnpinItem(const mojo::String& app_id) { |
235 std::string item_id(id.To<std::string>()); | 301 if (!app_id_to_shelf_id_.count(app_id.To<std::string>())) |
236 DCHECK(app_id_to_shelf_id_.count(item_id)); | 302 return; |
237 model_->RemoveItemAt(model_->ItemIndexByID(app_id_to_shelf_id_[item_id])); | 303 ShelfID shelf_id = app_id_to_shelf_id_[app_id.To<std::string>()]; |
| 304 ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id); |
| 305 DCHECK(item_delegate->pinned()); |
| 306 item_delegate->set_pinned(false); |
| 307 if (item_delegate->window_id_to_title().empty()) |
| 308 model_->RemoveItemAt(model_->ItemIndexByID(shelf_id)); |
238 } | 309 } |
239 | 310 |
240 void ShelfDelegateMus::OnUserWindowObserverAdded( | 311 void ShelfDelegateMus::OnUserWindowObserverAdded( |
241 mojo::Array<mash::wm::mojom::UserWindowPtr> user_windows) { | 312 mojo::Array<mash::wm::mojom::UserWindowPtr> user_windows) { |
242 for (size_t i = 0; i < user_windows.size(); ++i) | 313 for (size_t i = 0; i < user_windows.size(); ++i) |
243 OnUserWindowAdded(std::move(user_windows[i])); | 314 OnUserWindowAdded(std::move(user_windows[i])); |
244 } | 315 } |
245 | 316 |
246 void ShelfDelegateMus::OnUserWindowAdded( | 317 void ShelfDelegateMus::OnUserWindowAdded( |
247 mash::wm::mojom::UserWindowPtr user_window) { | 318 mash::wm::mojom::UserWindowPtr user_window) { |
| 319 DCHECK(!window_id_to_shelf_id_.count(user_window->window_id)); |
| 320 |
| 321 std::string app_id(user_window->window_app_id.To<std::string>()); |
| 322 if (app_id_to_shelf_id_.count(app_id)) { |
| 323 ShelfID shelf_id = app_id_to_shelf_id_[app_id]; |
| 324 window_id_to_shelf_id_.insert( |
| 325 std::make_pair(user_window->window_id, shelf_id)); |
| 326 |
| 327 ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id); |
| 328 item_delegate->AddWindow(user_window->window_id, |
| 329 user_window->window_title.To<base::string16>()); |
| 330 return; |
| 331 } |
| 332 |
| 333 ShelfID shelf_id = model_->next_id(); |
| 334 window_id_to_shelf_id_.insert( |
| 335 std::make_pair(user_window->window_id, shelf_id)); |
| 336 app_id_to_shelf_id_.insert(std::make_pair(app_id, shelf_id)); |
| 337 |
248 ShelfItem item; | 338 ShelfItem item; |
249 item.type = TYPE_PLATFORM_APP; | 339 item.type = TYPE_PLATFORM_APP; |
250 item.status = user_window->window_has_focus ? STATUS_ACTIVE : STATUS_RUNNING; | 340 item.status = user_window->window_has_focus ? STATUS_ACTIVE : STATUS_RUNNING; |
251 item.image = GetShelfIconFromSerializedBitmap(user_window->window_app_icon); | 341 item.image = GetShelfIconFromSerializedBitmap(user_window->window_app_icon); |
252 | |
253 ShelfID shelf_id = model_->next_id(); | |
254 window_id_to_shelf_id_.insert( | |
255 std::make_pair(user_window->window_id, shelf_id)); | |
256 model_->Add(item); | 342 model_->Add(item); |
257 | 343 |
258 std::unique_ptr<ShelfItemDelegate> item_delegate(new ShelfItemDelegateMus( | 344 std::unique_ptr<ShelfItemDelegateMus> item_delegate( |
259 user_window->window_id, user_window->window_title.To<base::string16>(), | 345 new ShelfItemDelegateMus(user_window_controller_.get())); |
260 user_window_controller_.get())); | 346 item_delegate->AddWindow(user_window->window_id, |
| 347 user_window->window_title.To<base::string16>()); |
261 Shell::GetInstance()->shelf_item_delegate_manager()->SetShelfItemDelegate( | 348 Shell::GetInstance()->shelf_item_delegate_manager()->SetShelfItemDelegate( |
262 shelf_id, std::move(item_delegate)); | 349 shelf_id, std::move(item_delegate)); |
263 } | 350 } |
264 | 351 |
265 void ShelfDelegateMus::OnUserWindowRemoved(uint32_t window_id) { | 352 void ShelfDelegateMus::OnUserWindowRemoved(uint32_t window_id) { |
266 DCHECK(window_id_to_shelf_id_.count(window_id)); | 353 DCHECK(window_id_to_shelf_id_.count(window_id)); |
267 model_->RemoveItemAt( | 354 ShelfID shelf_id = window_id_to_shelf_id_[window_id]; |
268 model_->ItemIndexByID(window_id_to_shelf_id_[window_id])); | 355 ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id); |
| 356 item_delegate->RemoveWindow(window_id); |
| 357 window_id_to_shelf_id_.erase(window_id); |
| 358 if (item_delegate->window_id_to_title().empty() && !item_delegate->pinned()) |
| 359 model_->RemoveItemAt(model_->ItemIndexByID(shelf_id)); |
269 } | 360 } |
270 | 361 |
271 void ShelfDelegateMus::OnUserWindowTitleChanged( | 362 void ShelfDelegateMus::OnUserWindowTitleChanged( |
272 uint32_t window_id, | 363 uint32_t window_id, |
273 const mojo::String& window_title) { | 364 const mojo::String& window_title) { |
274 DCHECK(window_id_to_shelf_id_.count(window_id)); | 365 DCHECK(window_id_to_shelf_id_.count(window_id)); |
275 ShelfID shelf_id = window_id_to_shelf_id_[window_id]; | 366 ShelfID shelf_id = window_id_to_shelf_id_[window_id]; |
276 ShelfItemDelegateManager* manager = | 367 ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id); |
277 Shell::GetInstance()->shelf_item_delegate_manager(); | 368 item_delegate->SetWindowTitle(window_id, window_title.To<base::string16>()); |
278 ShelfItemDelegate* delegate = manager->GetShelfItemDelegate(shelf_id); | |
279 DCHECK(delegate); | |
280 static_cast<ShelfItemDelegateMus*>(delegate)->UpdateTitle( | |
281 window_title.To<base::string16>()); | |
282 | 369 |
283 // There's nothing in the ShelfItem that needs to be updated. But we still | 370 // There's nothing in the ShelfItem that needs to be updated. But we still |
284 // need to update the ShelfModel so that the observers can pick up any | 371 // need to update the ShelfModel so that the observers can pick up any |
285 // changes. | 372 // changes. |
286 int index = model_->ItemIndexByID(shelf_id); | 373 int index = model_->ItemIndexByID(shelf_id); |
287 DCHECK_GE(index, 0); | 374 DCHECK_GE(index, 0); |
288 ShelfItems::const_iterator iter = model_->ItemByID(shelf_id); | 375 ShelfItems::const_iterator iter = model_->ItemByID(shelf_id); |
289 DCHECK(iter != model_->items().end()); | 376 DCHECK(iter != model_->items().end()); |
290 model_->Set(index, *iter); | 377 model_->Set(index, *iter); |
291 } | 378 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 StatusAreaWidget* status_widget = widget->status_area_widget(); | 417 StatusAreaWidget* status_widget = widget->status_area_widget(); |
331 mus::Window* status_window = | 418 mus::Window* status_window = |
332 aura::GetMusWindow(status_widget->GetNativeWindow()); | 419 aura::GetMusWindow(status_widget->GetNativeWindow()); |
333 gfx::Size status_size = status_widget->GetWindowBoundsInScreen().size(); | 420 gfx::Size status_size = status_widget->GetWindowBoundsInScreen().size(); |
334 status_window->SetSharedProperty<gfx::Size>( | 421 status_window->SetSharedProperty<gfx::Size>( |
335 mus::mojom::WindowManager::kPreferredSize_Property, status_size); | 422 mus::mojom::WindowManager::kPreferredSize_Property, status_size); |
336 } | 423 } |
337 | 424 |
338 } // namespace sysui | 425 } // namespace sysui |
339 } // namespace ash | 426 } // namespace ash |
OLD | NEW |