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(!windows_.count(id)); | |
50 windows_.insert(std::make_pair(id, title)); | |
51 } | |
52 void RemoveWindow(uint32_t id) { windows_.erase(id); } | |
53 void SetWindowTitle(uint32_t id, const base::string16& title) { | |
54 DCHECK(windows_.count(id)); | |
55 windows_[id] = title; | |
56 } | |
57 const std::map<uint32_t, base::string16>& windows() const { return windows_; } | |
58 | |
59 const base::string16& title() { return title_; } | |
60 void set_title(const base::string16& title) { title_ = title; } | |
49 | 61 |
50 private: | 62 private: |
63 // This application menu model for ShelfItemDelegateMus lists open windows. | |
64 class ShelfMenuModelMus : public ShelfMenuModel, | |
65 public ui::SimpleMenuModel::Delegate { | |
66 public: | |
67 explicit ShelfMenuModelMus(ShelfItemDelegateMus* item_delegate) | |
68 : ShelfMenuModel(this), item_delegate_(item_delegate) { | |
69 AddSeparator(ui::SPACING_SEPARATOR); | |
70 AddItem(0, item_delegate_->GetTitle()); | |
71 AddSeparator(ui::SPACING_SEPARATOR); | |
72 for (auto window : item_delegate_->windows()) | |
sky
2016/04/22 15:51:19
const auto&
msw
2016/04/22 19:02:17
Done.
| |
73 AddItem(window.first, window.second); | |
74 AddSeparator(ui::SPACING_SEPARATOR); | |
75 } | |
76 ~ShelfMenuModelMus() override {} | |
77 | |
78 // ShelfMenuModel: | |
79 bool IsCommandActive(int command_id) const override { return false; } | |
80 | |
81 // ui::SimpleMenuModel::Delegate: | |
82 bool IsCommandIdChecked(int command_id) const override { return false; } | |
83 bool IsCommandIdEnabled(int command_id) const override { | |
84 return command_id > 0; | |
85 } | |
86 bool GetAcceleratorForCommandId(int command_id, | |
87 ui::Accelerator* accelerator) override { | |
88 return false; | |
89 } | |
90 void ExecuteCommand(int command_id, int event_flags) override { | |
91 item_delegate_->user_window_controller_->FocusUserWindow(command_id); | |
92 } | |
93 | |
94 private: | |
95 ShelfItemDelegateMus* item_delegate_; | |
96 | |
97 DISALLOW_COPY_AND_ASSIGN(ShelfMenuModelMus); | |
98 }; | |
99 | |
51 // ShelfItemDelegate: | 100 // ShelfItemDelegate: |
52 ShelfItemDelegate::PerformedAction ItemSelected( | 101 ShelfItemDelegate::PerformedAction ItemSelected( |
53 const ui::Event& event) override { | 102 const ui::Event& event) override { |
54 if (window_id_ != 0) { | 103 if (windows_.size() == 1) { |
55 user_window_controller_->FocusUserWindow(window_id_); | 104 user_window_controller_->FocusUserWindow(windows_.begin()->first); |
56 return kExistingWindowActivated; | 105 return kExistingWindowActivated; |
57 } | 106 } |
58 NOTIMPLEMENTED(); | |
59 return kNoAction; | 107 return kNoAction; |
60 } | 108 } |
61 | 109 |
62 base::string16 GetTitle() override { return title_; } | 110 base::string16 GetTitle() override { |
111 return windows_.empty() ? title_ : windows_.begin()->second; | |
112 } | |
63 | 113 |
64 bool CanPin() const override { | 114 bool CanPin() const override { |
65 NOTIMPLEMENTED(); | 115 NOTIMPLEMENTED(); |
66 return false; | 116 return true; |
67 } | 117 } |
68 | 118 |
69 ShelfMenuModel* CreateApplicationMenu(int event_flags) override { | 119 ShelfMenuModel* CreateApplicationMenu(int event_flags) override { |
70 NOTIMPLEMENTED(); | 120 return new ShelfMenuModelMus(this); |
71 return nullptr; | |
72 } | 121 } |
73 | 122 |
74 bool IsDraggable() override { | 123 bool IsDraggable() override { |
75 NOTIMPLEMENTED(); | 124 NOTIMPLEMENTED(); |
76 return false; | 125 return false; |
77 } | 126 } |
78 | 127 |
79 bool ShouldShowTooltip() override { return true; } | 128 bool ShouldShowTooltip() override { return true; } |
80 | 129 |
81 void Close() override { NOTIMPLEMENTED(); } | 130 void Close() override { NOTIMPLEMENTED(); } |
82 | 131 |
83 // TODO(msw): Support multiple open windows per button. | 132 bool pinned_ = false; |
84 uint32_t window_id_; | 133 std::map<uint32_t, base::string16> windows_; |
sky
2016/04/22 15:51:19
This name is mildly confusing as as it's really wi
msw
2016/04/22 19:02:17
Renamed, clarity in identifier names is better tha
| |
85 base::string16 title_; | 134 base::string16 title_; |
86 UserWindowController* user_window_controller_; | 135 UserWindowController* user_window_controller_; |
87 | 136 |
88 DISALLOW_COPY_AND_ASSIGN(ShelfItemDelegateMus); | 137 DISALLOW_COPY_AND_ASSIGN(ShelfItemDelegateMus); |
89 }; | 138 }; |
90 | 139 |
140 ShelfItemDelegateMus* GetShelfItemDelegate(ShelfID shelf_id) { | |
141 return static_cast<ShelfItemDelegateMus*>( | |
142 Shell::GetInstance()->shelf_item_delegate_manager()->GetShelfItemDelegate( | |
143 shelf_id)); | |
144 } | |
145 | |
91 // Returns an icon image from an SkBitmap, or the default shelf icon | 146 // 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. | 147 // image if the bitmap is empty. Assumes the bitmap is a 1x icon. |
93 // TODO(jamescook): Support other scale factors. | 148 // TODO(jamescook): Support other scale factors. |
94 gfx::ImageSkia GetShelfIconFromBitmap(const SkBitmap& bitmap) { | 149 gfx::ImageSkia GetShelfIconFromBitmap(const SkBitmap& bitmap) { |
95 gfx::ImageSkia icon_image; | 150 gfx::ImageSkia icon_image; |
96 if (!bitmap.isNull()) { | 151 if (!bitmap.isNull()) { |
97 icon_image = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); | 152 icon_image = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); |
98 } else { | 153 } else { |
99 // Use default icon. | 154 // Use default icon. |
100 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 155 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
203 Shell::GetInstance()->SetShelfAlignment(value, Shell::GetPrimaryRootWindow()); | 258 Shell::GetInstance()->SetShelfAlignment(value, Shell::GetPrimaryRootWindow()); |
204 } | 259 } |
205 | 260 |
206 void ShelfDelegateMus::SetAutoHideBehavior( | 261 void ShelfDelegateMus::SetAutoHideBehavior( |
207 mash::shelf::mojom::AutoHideBehavior auto_hide) { | 262 mash::shelf::mojom::AutoHideBehavior auto_hide) { |
208 ShelfAutoHideBehavior value = static_cast<ShelfAutoHideBehavior>(auto_hide); | 263 ShelfAutoHideBehavior value = static_cast<ShelfAutoHideBehavior>(auto_hide); |
209 Shell::GetInstance()->SetShelfAutoHideBehavior(value, | 264 Shell::GetInstance()->SetShelfAutoHideBehavior(value, |
210 Shell::GetPrimaryRootWindow()); | 265 Shell::GetPrimaryRootWindow()); |
211 } | 266 } |
212 | 267 |
213 void ShelfDelegateMus::AddItem( | 268 void ShelfDelegateMus::PinItem( |
214 mash::shelf::mojom::ShelfItemPtr item, | 269 mash::shelf::mojom::ShelfItemPtr item, |
215 mash::shelf::mojom::ShelfItemDelegateAssociatedPtrInfo delegate) { | 270 mash::shelf::mojom::ShelfItemDelegateAssociatedPtrInfo delegate) { |
271 std::string app_id(item->app_id.To<std::string>()); | |
272 if (app_id_to_shelf_id_.count(app_id)) { | |
273 ShelfID shelf_id = app_id_to_shelf_id_[app_id]; | |
274 ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id); | |
275 item_delegate->set_pinned(true); | |
276 return; | |
277 } | |
278 | |
279 ShelfID shelf_id = model_->next_id(); | |
280 app_id_to_shelf_id_.insert(std::make_pair(app_id, shelf_id)); | |
281 | |
216 ShelfItem shelf_item; | 282 ShelfItem shelf_item; |
217 shelf_item.type = TYPE_APP_SHORTCUT; | 283 shelf_item.type = TYPE_APP_SHORTCUT; |
218 shelf_item.status = STATUS_CLOSED; | 284 shelf_item.status = STATUS_CLOSED; |
219 shelf_item.image = GetShelfIconFromBitmap(item->image.To<SkBitmap>()); | 285 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); | 286 model_->Add(shelf_item); |
227 | 287 |
228 std::unique_ptr<ShelfItemDelegateMus> item_delegate(new ShelfItemDelegateMus( | 288 std::unique_ptr<ShelfItemDelegateMus> item_delegate( |
229 0, item->title.To<base::string16>(), user_window_controller_.get())); | 289 new ShelfItemDelegateMus(user_window_controller_.get())); |
290 item_delegate->set_pinned(true); | |
291 item_delegate->set_title(item->app_title.To<base::string16>()); | |
230 Shell::GetInstance()->shelf_item_delegate_manager()->SetShelfItemDelegate( | 292 Shell::GetInstance()->shelf_item_delegate_manager()->SetShelfItemDelegate( |
231 shelf_id, std::move(item_delegate)); | 293 shelf_id, std::move(item_delegate)); |
232 } | 294 } |
233 | 295 |
234 void ShelfDelegateMus::RemoveItem(const mojo::String& id) { | 296 void ShelfDelegateMus::UnpinItem(const mojo::String& app_id) { |
235 std::string item_id(id.To<std::string>()); | 297 DCHECK(app_id_to_shelf_id_.count(app_id.To<std::string>())); |
sky
2016/04/22 15:51:19
Don't trust a client to do the right thing with mo
msw
2016/04/22 19:02:17
Added early return. I think this is probably okay
| |
236 DCHECK(app_id_to_shelf_id_.count(item_id)); | 298 ShelfID shelf_id = app_id_to_shelf_id_[app_id.To<std::string>()]; |
237 model_->RemoveItemAt(model_->ItemIndexByID(app_id_to_shelf_id_[item_id])); | 299 ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id); |
300 DCHECK(item_delegate->pinned()); | |
301 item_delegate->set_pinned(false); | |
302 if (item_delegate->windows().empty()) | |
303 model_->RemoveItemAt(model_->ItemIndexByID(shelf_id)); | |
238 } | 304 } |
239 | 305 |
240 void ShelfDelegateMus::OnUserWindowObserverAdded( | 306 void ShelfDelegateMus::OnUserWindowObserverAdded( |
241 mojo::Array<mash::wm::mojom::UserWindowPtr> user_windows) { | 307 mojo::Array<mash::wm::mojom::UserWindowPtr> user_windows) { |
242 for (size_t i = 0; i < user_windows.size(); ++i) | 308 for (size_t i = 0; i < user_windows.size(); ++i) |
243 OnUserWindowAdded(std::move(user_windows[i])); | 309 OnUserWindowAdded(std::move(user_windows[i])); |
244 } | 310 } |
245 | 311 |
246 void ShelfDelegateMus::OnUserWindowAdded( | 312 void ShelfDelegateMus::OnUserWindowAdded( |
247 mash::wm::mojom::UserWindowPtr user_window) { | 313 mash::wm::mojom::UserWindowPtr user_window) { |
314 DCHECK(!window_id_to_shelf_id_.count(user_window->window_id)); | |
315 | |
316 std::string app_id(user_window->window_app_id.To<std::string>()); | |
317 if (app_id_to_shelf_id_.count(app_id)) { | |
318 ShelfID shelf_id = app_id_to_shelf_id_[app_id]; | |
319 window_id_to_shelf_id_.insert( | |
320 std::make_pair(user_window->window_id, shelf_id)); | |
321 | |
322 ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id); | |
323 item_delegate->AddWindow(user_window->window_id, | |
324 user_window->window_title.To<base::string16>()); | |
325 return; | |
326 } | |
327 | |
328 ShelfID shelf_id = model_->next_id(); | |
329 window_id_to_shelf_id_.insert( | |
330 std::make_pair(user_window->window_id, shelf_id)); | |
331 app_id_to_shelf_id_.insert(std::make_pair(app_id, shelf_id)); | |
332 | |
248 ShelfItem item; | 333 ShelfItem item; |
249 item.type = TYPE_PLATFORM_APP; | 334 item.type = TYPE_PLATFORM_APP; |
250 item.status = user_window->window_has_focus ? STATUS_ACTIVE : STATUS_RUNNING; | 335 item.status = user_window->window_has_focus ? STATUS_ACTIVE : STATUS_RUNNING; |
251 item.image = GetShelfIconFromSerializedBitmap(user_window->window_app_icon); | 336 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); | 337 model_->Add(item); |
257 | 338 |
258 std::unique_ptr<ShelfItemDelegate> item_delegate(new ShelfItemDelegateMus( | 339 std::unique_ptr<ShelfItemDelegateMus> item_delegate( |
259 user_window->window_id, user_window->window_title.To<base::string16>(), | 340 new ShelfItemDelegateMus(user_window_controller_.get())); |
260 user_window_controller_.get())); | 341 item_delegate->AddWindow(user_window->window_id, |
342 user_window->window_title.To<base::string16>()); | |
261 Shell::GetInstance()->shelf_item_delegate_manager()->SetShelfItemDelegate( | 343 Shell::GetInstance()->shelf_item_delegate_manager()->SetShelfItemDelegate( |
262 shelf_id, std::move(item_delegate)); | 344 shelf_id, std::move(item_delegate)); |
263 } | 345 } |
264 | 346 |
265 void ShelfDelegateMus::OnUserWindowRemoved(uint32_t window_id) { | 347 void ShelfDelegateMus::OnUserWindowRemoved(uint32_t window_id) { |
266 DCHECK(window_id_to_shelf_id_.count(window_id)); | 348 DCHECK(window_id_to_shelf_id_.count(window_id)); |
267 model_->RemoveItemAt( | 349 ShelfID shelf_id = window_id_to_shelf_id_[window_id]; |
268 model_->ItemIndexByID(window_id_to_shelf_id_[window_id])); | 350 ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id); |
351 item_delegate->RemoveWindow(window_id); | |
352 window_id_to_shelf_id_.erase(window_id); | |
353 if (item_delegate->windows().empty() && !item_delegate->pinned()) | |
354 model_->RemoveItemAt(model_->ItemIndexByID(shelf_id)); | |
269 } | 355 } |
270 | 356 |
271 void ShelfDelegateMus::OnUserWindowTitleChanged( | 357 void ShelfDelegateMus::OnUserWindowTitleChanged( |
272 uint32_t window_id, | 358 uint32_t window_id, |
273 const mojo::String& window_title) { | 359 const mojo::String& window_title) { |
274 DCHECK(window_id_to_shelf_id_.count(window_id)); | 360 DCHECK(window_id_to_shelf_id_.count(window_id)); |
275 ShelfID shelf_id = window_id_to_shelf_id_[window_id]; | 361 ShelfID shelf_id = window_id_to_shelf_id_[window_id]; |
276 ShelfItemDelegateManager* manager = | 362 ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id); |
277 Shell::GetInstance()->shelf_item_delegate_manager(); | 363 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 | 364 |
283 // There's nothing in the ShelfItem that needs to be updated. But we still | 365 // 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 | 366 // need to update the ShelfModel so that the observers can pick up any |
285 // changes. | 367 // changes. |
286 int index = model_->ItemIndexByID(shelf_id); | 368 int index = model_->ItemIndexByID(shelf_id); |
287 DCHECK_GE(index, 0); | 369 DCHECK_GE(index, 0); |
288 ShelfItems::const_iterator iter = model_->ItemByID(shelf_id); | 370 ShelfItems::const_iterator iter = model_->ItemByID(shelf_id); |
289 DCHECK(iter != model_->items().end()); | 371 DCHECK(iter != model_->items().end()); |
290 model_->Set(index, *iter); | 372 model_->Set(index, *iter); |
291 } | 373 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
330 StatusAreaWidget* status_widget = widget->status_area_widget(); | 412 StatusAreaWidget* status_widget = widget->status_area_widget(); |
331 mus::Window* status_window = | 413 mus::Window* status_window = |
332 aura::GetMusWindow(status_widget->GetNativeWindow()); | 414 aura::GetMusWindow(status_widget->GetNativeWindow()); |
333 gfx::Size status_size = status_widget->GetWindowBoundsInScreen().size(); | 415 gfx::Size status_size = status_widget->GetWindowBoundsInScreen().size(); |
334 status_window->SetSharedProperty<gfx::Size>( | 416 status_window->SetSharedProperty<gfx::Size>( |
335 mus::mojom::WindowManager::kPreferredSize_Property, status_size); | 417 mus::mojom::WindowManager::kPreferredSize_Property, status_size); |
336 } | 418 } |
337 | 419 |
338 } // namespace sysui | 420 } // namespace sysui |
339 } // namespace ash | 421 } // namespace ash |
OLD | NEW |