Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/common/shelf/shelf_model.h" | 5 #include "ash/common/shelf/shelf_model.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "ash/common/shelf/shelf_item_delegate.h" | |
| 9 #include "ash/common/shelf/shelf_model_observer.h" | 10 #include "ash/common/shelf/shelf_model_observer.h" |
| 10 | 11 |
| 11 namespace ash { | 12 namespace ash { |
| 12 | 13 |
| 13 namespace { | 14 namespace { |
| 14 | 15 |
| 15 int ShelfItemTypeToWeight(ShelfItemType type) { | 16 int ShelfItemTypeToWeight(ShelfItemType type) { |
| 16 switch (type) { | 17 switch (type) { |
| 17 case TYPE_APP_LIST: | 18 case TYPE_APP_LIST: |
| 18 // TODO(skuhne): If the app list item becomes movable again, this need | 19 // TODO(skuhne): If the app list item becomes movable again, this need |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 42 bool CompareByWeight(const ShelfItem& a, const ShelfItem& b) { | 43 bool CompareByWeight(const ShelfItem& a, const ShelfItem& b) { |
| 43 return ShelfItemTypeToWeight(a.type) < ShelfItemTypeToWeight(b.type); | 44 return ShelfItemTypeToWeight(a.type) < ShelfItemTypeToWeight(b.type); |
| 44 } | 45 } |
| 45 | 46 |
| 46 } // namespace | 47 } // namespace |
| 47 | 48 |
| 48 ShelfModel::ShelfModel() : next_id_(1), status_(STATUS_NORMAL) {} | 49 ShelfModel::ShelfModel() : next_id_(1), status_(STATUS_NORMAL) {} |
| 49 | 50 |
| 50 ShelfModel::~ShelfModel() {} | 51 ShelfModel::~ShelfModel() {} |
| 51 | 52 |
| 53 void ShelfModel::Shutdown() { | |
| 54 // Some ShelfItemDelegates access this model in their destructors and hence | |
|
msw
2016/07/21 21:30:53
Would it be sufficient to inline this in the dtor?
James Cook
2016/07/22 01:20:07
I need to do this in an explicit cleanup pass from
msw
2016/07/22 01:49:51
It's not clear to me why this would need to happen
| |
| 55 // need early cleanup. | |
| 56 id_to_item_delegate_map_.clear(); | |
| 57 } | |
| 58 | |
| 52 int ShelfModel::Add(const ShelfItem& item) { | 59 int ShelfModel::Add(const ShelfItem& item) { |
| 53 return AddAt(items_.size(), item); | 60 return AddAt(items_.size(), item); |
| 54 } | 61 } |
| 55 | 62 |
| 56 int ShelfModel::AddAt(int index, const ShelfItem& item) { | 63 int ShelfModel::AddAt(int index, const ShelfItem& item) { |
| 57 index = ValidateInsertionIndex(item.type, index); | 64 index = ValidateInsertionIndex(item.type, index); |
| 58 items_.insert(items_.begin() + index, item); | 65 items_.insert(items_.begin() + index, item); |
| 59 items_[index].id = next_id_++; | 66 items_[index].id = next_id_++; |
| 60 FOR_EACH_OBSERVER(ShelfModelObserver, observers_, ShelfItemAdded(index)); | 67 FOR_EACH_OBSERVER(ShelfModelObserver, observers_, ShelfItemAdded(index)); |
| 61 return index; | 68 return index; |
| 62 } | 69 } |
| 63 | 70 |
| 64 void ShelfModel::RemoveItemAt(int index) { | 71 void ShelfModel::RemoveItemAt(int index) { |
| 65 DCHECK(index >= 0 && index < item_count()); | 72 DCHECK(index >= 0 && index < item_count()); |
| 66 // The app list and browser shortcut can't be removed. | 73 // The app list and browser shortcut can't be removed. |
| 67 DCHECK(items_[index].type != TYPE_APP_LIST && | 74 DCHECK(items_[index].type != TYPE_APP_LIST && |
| 68 items_[index].type != TYPE_BROWSER_SHORTCUT); | 75 items_[index].type != TYPE_BROWSER_SHORTCUT); |
| 69 ShelfID id = items_[index].id; | 76 ShelfID id = items_[index].id; |
| 70 items_.erase(items_.begin() + index); | 77 items_.erase(items_.begin() + index); |
| 78 RemoveShelfItemDelegate(id); | |
| 79 // TODO(jamescook): Fold this into ShelfItemRemoved in existing observers. | |
| 80 FOR_EACH_OBSERVER(ShelfModelObserver, observers_, | |
| 81 OnSetShelfItemDelegate(id, nullptr)); | |
| 71 FOR_EACH_OBSERVER(ShelfModelObserver, observers_, | 82 FOR_EACH_OBSERVER(ShelfModelObserver, observers_, |
| 72 ShelfItemRemoved(index, id)); | 83 ShelfItemRemoved(index, id)); |
| 73 } | 84 } |
| 74 | 85 |
| 75 void ShelfModel::Move(int index, int target_index) { | 86 void ShelfModel::Move(int index, int target_index) { |
| 76 if (index == target_index) | 87 if (index == target_index) |
| 77 return; | 88 return; |
| 78 // TODO: this needs to enforce valid ranges. | 89 // TODO: this needs to enforce valid ranges. |
| 79 ShelfItem item(items_[index]); | 90 ShelfItem item(items_[index]); |
| 80 items_.erase(items_.begin() + index); | 91 items_.erase(items_.begin() + index); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 } | 155 } |
| 145 | 156 |
| 146 int ShelfModel::FirstPanelIndex() const { | 157 int ShelfModel::FirstPanelIndex() const { |
| 147 ShelfItem weight_dummy; | 158 ShelfItem weight_dummy; |
| 148 weight_dummy.type = TYPE_APP_PANEL; | 159 weight_dummy.type = TYPE_APP_PANEL; |
| 149 return std::lower_bound(items_.begin(), items_.end(), weight_dummy, | 160 return std::lower_bound(items_.begin(), items_.end(), weight_dummy, |
| 150 CompareByWeight) - | 161 CompareByWeight) - |
| 151 items_.begin(); | 162 items_.begin(); |
| 152 } | 163 } |
| 153 | 164 |
| 165 void ShelfModel::SetShelfItemDelegate( | |
| 166 ShelfID id, | |
| 167 std::unique_ptr<ShelfItemDelegate> item_delegate) { | |
| 168 // If another ShelfItemDelegate is already registered for |id|, we assume | |
| 169 // that this request is replacing ShelfItemDelegate for |id| with | |
| 170 // |item_delegate|. | |
| 171 RemoveShelfItemDelegate(id); | |
| 172 | |
| 173 FOR_EACH_OBSERVER(ShelfModelObserver, observers_, | |
| 174 OnSetShelfItemDelegate(id, item_delegate.get())); | |
| 175 | |
| 176 id_to_item_delegate_map_[id] = std::move(item_delegate); | |
| 177 } | |
| 178 | |
| 179 ShelfItemDelegate* ShelfModel::GetShelfItemDelegate(ShelfID id) { | |
| 180 if (ItemIndexByID(id) == -1) | |
|
msw
2016/07/21 21:30:53
Is checking for the item index useful? Consider th
James Cook
2016/07/22 01:20:07
Done. I wonder if this could be related to the she
| |
| 181 return nullptr; | |
| 182 // Each ShelfItem has to have a ShelfItemDelegate. | |
| 183 DCHECK(id_to_item_delegate_map_.find(id) != id_to_item_delegate_map_.end()); | |
| 184 return id_to_item_delegate_map_[id].get(); | |
| 185 } | |
| 186 | |
| 154 void ShelfModel::AddObserver(ShelfModelObserver* observer) { | 187 void ShelfModel::AddObserver(ShelfModelObserver* observer) { |
| 155 observers_.AddObserver(observer); | 188 observers_.AddObserver(observer); |
| 156 } | 189 } |
| 157 | 190 |
| 158 void ShelfModel::RemoveObserver(ShelfModelObserver* observer) { | 191 void ShelfModel::RemoveObserver(ShelfModelObserver* observer) { |
| 159 observers_.RemoveObserver(observer); | 192 observers_.RemoveObserver(observer); |
| 160 } | 193 } |
| 161 | 194 |
| 162 int ShelfModel::ValidateInsertionIndex(ShelfItemType type, int index) const { | 195 int ShelfModel::ValidateInsertionIndex(ShelfItemType type, int index) const { |
| 163 DCHECK(index >= 0 && index <= item_count() + 1); | 196 DCHECK(index >= 0 && index <= item_count() + 1); |
| 164 | 197 |
| 165 // Clamp |index| to the allowed range for the type as determined by |weight|. | 198 // Clamp |index| to the allowed range for the type as determined by |weight|. |
| 166 ShelfItem weight_dummy; | 199 ShelfItem weight_dummy; |
| 167 weight_dummy.type = type; | 200 weight_dummy.type = type; |
| 168 index = std::max(std::lower_bound(items_.begin(), items_.end(), weight_dummy, | 201 index = std::max(std::lower_bound(items_.begin(), items_.end(), weight_dummy, |
| 169 CompareByWeight) - | 202 CompareByWeight) - |
| 170 items_.begin(), | 203 items_.begin(), |
| 171 static_cast<ShelfItems::difference_type>(index)); | 204 static_cast<ShelfItems::difference_type>(index)); |
| 172 index = std::min(std::upper_bound(items_.begin(), items_.end(), weight_dummy, | 205 index = std::min(std::upper_bound(items_.begin(), items_.end(), weight_dummy, |
| 173 CompareByWeight) - | 206 CompareByWeight) - |
| 174 items_.begin(), | 207 items_.begin(), |
| 175 static_cast<ShelfItems::difference_type>(index)); | 208 static_cast<ShelfItems::difference_type>(index)); |
| 176 | 209 |
| 177 return index; | 210 return index; |
| 178 } | 211 } |
| 179 | 212 |
| 213 void ShelfModel::RemoveShelfItemDelegate(ShelfID id) { | |
| 214 if (id_to_item_delegate_map_.find(id) != id_to_item_delegate_map_.end()) | |
| 215 id_to_item_delegate_map_.erase(id); | |
| 216 } | |
| 217 | |
| 180 } // namespace ash | 218 } // namespace ash |
| OLD | NEW |