| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 #ifndef UI_BASE_MODELS_LIST_MODEL_H_ | 5 #ifndef UI_BASE_MODELS_LIST_MODEL_H_ |
| 6 #define UI_BASE_MODELS_LIST_MODEL_H_ | 6 #define UI_BASE_MODELS_LIST_MODEL_H_ |
| 7 | 7 |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 | 9 |
| 10 #include <memory> | 10 #include <memory> |
| 11 #include <utility> | 11 #include <utility> |
| 12 #include <vector> |
| 12 | 13 |
| 13 #include "base/logging.h" | 14 #include "base/logging.h" |
| 14 #include "base/macros.h" | 15 #include "base/macros.h" |
| 15 #include "base/memory/ptr_util.h" | 16 #include "base/memory/ptr_util.h" |
| 16 #include "base/memory/scoped_vector.h" | |
| 17 #include "base/observer_list.h" | 17 #include "base/observer_list.h" |
| 18 #include "ui/base/models/list_model_observer.h" | 18 #include "ui/base/models/list_model_observer.h" |
| 19 | 19 |
| 20 namespace ui { | 20 namespace ui { |
| 21 | 21 |
| 22 // A list model that manages a list of ItemType pointers. Items added to the | 22 // A list model that manages a list of ItemType pointers. Items added to the |
| 23 // model are owned by the model. An item can be taken out of the model by | 23 // model are owned by the model. An item can be taken out of the model by |
| 24 // RemoveAt. | 24 // RemoveAt. |
| 25 template <class ItemType> | 25 template <class ItemType> |
| 26 class ListModel { | 26 class ListModel { |
| 27 public: | 27 public: |
| 28 using ItemList = std::vector<std::unique_ptr<ItemType>>; |
| 29 |
| 28 ListModel() {} | 30 ListModel() {} |
| 29 ~ListModel() {} | 31 ~ListModel() {} |
| 30 | 32 |
| 31 // Adds |item| at the |index| into |items_|. Takes ownership of |item|. | 33 // Adds |item| at the |index| into |items_|. Returns a raw pointer. |
| 32 void AddAt(size_t index, ItemType* item) { | 34 ItemType* AddAt(size_t index, std::unique_ptr<ItemType> item) { |
| 33 DCHECK_LE(index, item_count()); | 35 DCHECK_LE(index, item_count()); |
| 34 items_.insert(items_.begin() + index, item); | 36 ItemType* item_ptr = item.get(); |
| 37 items_.insert(items_.begin() + index, std::move(item)); |
| 35 NotifyItemsAdded(index, 1); | 38 NotifyItemsAdded(index, 1); |
| 39 return item_ptr; |
| 36 } | 40 } |
| 37 | 41 |
| 38 // Convenience function to append an item to the model. | 42 // Convenience function to append an item to the model. |
| 39 void Add(ItemType* item) { | 43 ItemType* Add(std::unique_ptr<ItemType> item) { |
| 40 AddAt(item_count(), item); | 44 return AddAt(item_count(), std::move(item)); |
| 41 } | 45 } |
| 42 | 46 |
| 43 // Removes the item at |index| from |items_| without deleting it. | 47 // Removes the item at |index| from |items_| without deleting it. |
| 44 // Returns a scoped pointer containing the removed item. | 48 // Returns a scoped pointer containing the removed item. |
| 45 std::unique_ptr<ItemType> RemoveAt(size_t index) { | 49 std::unique_ptr<ItemType> RemoveAt(size_t index) { |
| 46 DCHECK_LT(index, item_count()); | 50 DCHECK_LT(index, item_count()); |
| 47 ItemType* item = items_[index]; | 51 std::unique_ptr<ItemType> item = std::move(items_[index]); |
| 48 items_.weak_erase(items_.begin() + index); | 52 items_.erase(items_.begin() + index); |
| 49 NotifyItemsRemoved(index, 1); | 53 NotifyItemsRemoved(index, 1); |
| 50 return base::WrapUnique<ItemType>(item); | 54 return item; |
| 51 } | 55 } |
| 52 | 56 |
| 53 // Removes all items from the model. This does NOT delete the items. | 57 // Removes all items from the model without deleting them. |
| 54 void RemoveAll() { | 58 // Returns a vector containing the removed items. |
| 55 size_t count = item_count(); | 59 ItemList RemoveAll() { |
| 56 items_.weak_clear(); | 60 ItemList result; |
| 57 NotifyItemsRemoved(0, count); | 61 result.swap(items_); |
| 62 NotifyItemsRemoved(0, result.size()); |
| 63 return result; |
| 58 } | 64 } |
| 59 | 65 |
| 60 // Removes the item at |index| from |items_| and deletes it. | 66 // Removes the item at |index| from |items_| and deletes it. |
| 61 void DeleteAt(size_t index) { | 67 void DeleteAt(size_t index) { |
| 62 std::unique_ptr<ItemType> item = RemoveAt(index); | 68 std::unique_ptr<ItemType> item = RemoveAt(index); |
| 63 // |item| will be deleted on destruction. | 69 // |item| will be deleted on destruction. |
| 64 } | 70 } |
| 65 | 71 |
| 66 // Removes and deletes all items from the model. | 72 // Removes and deletes all items from the model. |
| 67 void DeleteAll() { | 73 void DeleteAll() { |
| 68 ScopedVector<ItemType> to_be_deleted(std::move(items_)); | 74 ItemList to_be_deleted; |
| 75 to_be_deleted.swap(items_); |
| 69 NotifyItemsRemoved(0, to_be_deleted.size()); | 76 NotifyItemsRemoved(0, to_be_deleted.size()); |
| 70 } | 77 } |
| 71 | 78 |
| 72 // Moves the item at |index| to |target_index|. |target_index| is in terms | 79 // Moves the item at |index| to |target_index|. |target_index| is in terms |
| 73 // of the model *after* the item at |index| is removed. | 80 // of the model *after* the item at |index| is removed. |
| 74 void Move(size_t index, size_t target_index) { | 81 void Move(size_t index, size_t target_index) { |
| 75 DCHECK_LT(index, item_count()); | 82 DCHECK_LT(index, item_count()); |
| 76 DCHECK_LT(target_index, item_count()); | 83 DCHECK_LT(target_index, item_count()); |
| 77 | 84 |
| 78 if (index == target_index) | 85 if (index == target_index) |
| 79 return; | 86 return; |
| 80 | 87 |
| 81 ItemType* item = items_[index]; | 88 std::unique_ptr<ItemType> item = std::move(items_[index]); |
| 82 items_.weak_erase(items_.begin() + index); | 89 items_.erase(items_.begin() + index); |
| 83 items_.insert(items_.begin() + target_index, item); | 90 items_.insert(items_.begin() + target_index, std::move(item)); |
| 84 NotifyItemMoved(index, target_index); | 91 NotifyItemMoved(index, target_index); |
| 85 } | 92 } |
| 86 | 93 |
| 87 void AddObserver(ListModelObserver* observer) { | 94 void AddObserver(ListModelObserver* observer) { |
| 88 observers_.AddObserver(observer); | 95 observers_.AddObserver(observer); |
| 89 } | 96 } |
| 90 | 97 |
| 91 void RemoveObserver(ListModelObserver* observer) { | 98 void RemoveObserver(ListModelObserver* observer) { |
| 92 observers_.RemoveObserver(observer); | 99 observers_.RemoveObserver(observer); |
| 93 } | 100 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 113 void NotifyItemsChanged(size_t start, size_t count) { | 120 void NotifyItemsChanged(size_t start, size_t count) { |
| 114 FOR_EACH_OBSERVER(ListModelObserver, | 121 FOR_EACH_OBSERVER(ListModelObserver, |
| 115 observers_, | 122 observers_, |
| 116 ListItemsChanged(start, count)); | 123 ListItemsChanged(start, count)); |
| 117 } | 124 } |
| 118 | 125 |
| 119 size_t item_count() const { return items_.size(); } | 126 size_t item_count() const { return items_.size(); } |
| 120 | 127 |
| 121 const ItemType* GetItemAt(size_t index) const { | 128 const ItemType* GetItemAt(size_t index) const { |
| 122 DCHECK_LT(index, item_count()); | 129 DCHECK_LT(index, item_count()); |
| 123 return items_[index]; | 130 return items_[index].get(); |
| 124 } | 131 } |
| 125 ItemType* GetItemAt(size_t index) { | 132 ItemType* GetItemAt(size_t index) { |
| 126 return const_cast<ItemType*>( | 133 return const_cast<ItemType*>( |
| 127 const_cast<const ListModel<ItemType>*>(this)->GetItemAt(index)); | 134 const_cast<const ListModel<ItemType>*>(this)->GetItemAt(index)); |
| 128 } | 135 } |
| 129 | 136 |
| 130 // Iteration interface. | 137 // Iteration interface. |
| 131 typename ScopedVector<ItemType>::iterator begin() { return items_.begin(); } | 138 typename ItemList::iterator begin() { return items_.begin(); } |
| 132 typename ScopedVector<ItemType>::const_iterator begin() const { | 139 typename ItemList::const_iterator begin() const { return items_.begin(); } |
| 133 return items_.begin(); | 140 typename ItemList::iterator end() { return items_.end(); } |
| 134 } | 141 typename ItemList::const_iterator end() const { return items_.end(); } |
| 135 typename ScopedVector<ItemType>::iterator end() { return items_.end(); } | |
| 136 typename ScopedVector<ItemType>::const_iterator end() const { | |
| 137 return items_.end(); | |
| 138 } | |
| 139 | 142 |
| 140 private: | 143 private: |
| 141 ScopedVector<ItemType> items_; | 144 ItemList items_; |
| 142 base::ObserverList<ListModelObserver> observers_; | 145 base::ObserverList<ListModelObserver> observers_; |
| 143 | 146 |
| 144 DISALLOW_COPY_AND_ASSIGN(ListModel<ItemType>); | 147 DISALLOW_COPY_AND_ASSIGN(ListModel<ItemType>); |
| 145 }; | 148 }; |
| 146 | 149 |
| 147 } // namespace ui | 150 } // namespace ui |
| 148 | 151 |
| 149 #endif // UI_BASE_MODELS_LIST_MODEL_H_ | 152 #endif // UI_BASE_MODELS_LIST_MODEL_H_ |
| OLD | NEW |