Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Side by Side Diff: ash/common/shelf/shelf_model.cc

Issue 2736573002: chromeos: Move files in //ash/common to //ash, part 2 (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ash/common/shelf/shelf_model.h ('k') | ash/common/shelf/shelf_model_observer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ash/common/shelf/shelf_model.h"
6
7 #include <algorithm>
8
9 #include "ash/common/shelf/shelf_item_delegate.h"
10 #include "ash/common/shelf/shelf_model_observer.h"
11
12 namespace ash {
13
14 namespace {
15
16 int ShelfItemTypeToWeight(ShelfItemType type) {
17 switch (type) {
18 case TYPE_APP_LIST:
19 // TODO(skuhne): If the app list item becomes movable again, this need
20 // to be a fallthrough.
21 return 0;
22 case TYPE_BROWSER_SHORTCUT:
23 case TYPE_APP_SHORTCUT:
24 return 1;
25 case TYPE_APP:
26 return 2;
27 case TYPE_DIALOG:
28 return 3;
29 case TYPE_APP_PANEL:
30 return 4;
31 case TYPE_UNDEFINED:
32 NOTREACHED() << "ShelfItemType must be set";
33 return -1;
34 }
35
36 NOTREACHED() << "Invalid type " << type;
37 return 1;
38 }
39
40 bool CompareByWeight(const ShelfItem& a, const ShelfItem& b) {
41 return ShelfItemTypeToWeight(a.type) < ShelfItemTypeToWeight(b.type);
42 }
43
44 } // namespace
45
46 ShelfModel::ShelfModel() : next_id_(1) {}
47
48 ShelfModel::~ShelfModel() {}
49
50 void ShelfModel::DestroyItemDelegates() {
51 // Some ShelfItemDelegates access this model in their destructors and hence
52 // need early cleanup.
53 id_to_item_delegate_map_.clear();
54 }
55
56 int ShelfModel::Add(const ShelfItem& item) {
57 return AddAt(items_.size(), item);
58 }
59
60 int ShelfModel::AddAt(int index, const ShelfItem& item) {
61 index = ValidateInsertionIndex(item.type, index);
62 items_.insert(items_.begin() + index, item);
63 items_[index].id = next_id_++;
64 for (auto& observer : observers_)
65 observer.ShelfItemAdded(index);
66 return index;
67 }
68
69 void ShelfModel::RemoveItemAt(int index) {
70 DCHECK(index >= 0 && index < item_count());
71 ShelfID id = items_[index].id;
72 items_.erase(items_.begin() + index);
73 RemoveShelfItemDelegate(id);
74 // TODO(jamescook): Fold this into ShelfItemRemoved in existing observers.
75 for (auto& observer : observers_)
76 observer.OnSetShelfItemDelegate(id, nullptr);
77 for (auto& observer : observers_)
78 observer.ShelfItemRemoved(index, id);
79 }
80
81 void ShelfModel::Move(int index, int target_index) {
82 if (index == target_index)
83 return;
84 // TODO: this needs to enforce valid ranges.
85 ShelfItem item(items_[index]);
86 items_.erase(items_.begin() + index);
87 items_.insert(items_.begin() + target_index, item);
88 for (auto& observer : observers_)
89 observer.ShelfItemMoved(index, target_index);
90 }
91
92 void ShelfModel::Set(int index, const ShelfItem& item) {
93 if (index < 0 || index >= item_count()) {
94 NOTREACHED();
95 return;
96 }
97
98 int new_index = item.type == items_[index].type
99 ? index
100 : ValidateInsertionIndex(item.type, index);
101
102 ShelfItem old_item(items_[index]);
103 items_[index] = item;
104 items_[index].id = old_item.id;
105 for (auto& observer : observers_)
106 observer.ShelfItemChanged(index, old_item);
107
108 // If the type changes confirm that the item is still in the right order.
109 if (new_index != index) {
110 // The move function works by removing one item and then inserting it at the
111 // new location. However - by removing the item first the order will change
112 // so that our target index needs to be corrected.
113 // TODO(skuhne): Moving this into the Move function breaks lots of unit
114 // tests. So several functions were already using this incorrectly.
115 // That needs to be cleaned up.
116 if (index < new_index)
117 new_index--;
118
119 Move(index, new_index);
120 }
121 }
122
123 int ShelfModel::ItemIndexByID(ShelfID id) const {
124 ShelfItems::const_iterator i = ItemByID(id);
125 return i == items_.end() ? -1 : static_cast<int>(i - items_.begin());
126 }
127
128 int ShelfModel::GetItemIndexForType(ShelfItemType type) {
129 for (size_t i = 0; i < items_.size(); ++i) {
130 if (items_[i].type == type)
131 return i;
132 }
133 return -1;
134 }
135
136 ShelfItems::const_iterator ShelfModel::ItemByID(int id) const {
137 for (ShelfItems::const_iterator i = items_.begin(); i != items_.end(); ++i) {
138 if (i->id == id)
139 return i;
140 }
141 return items_.end();
142 }
143
144 int ShelfModel::FirstRunningAppIndex() const {
145 ShelfItem weight_dummy;
146 weight_dummy.type = TYPE_APP;
147 return std::lower_bound(items_.begin(), items_.end(), weight_dummy,
148 CompareByWeight) -
149 items_.begin();
150 }
151
152 int ShelfModel::FirstPanelIndex() const {
153 ShelfItem weight_dummy;
154 weight_dummy.type = TYPE_APP_PANEL;
155 return std::lower_bound(items_.begin(), items_.end(), weight_dummy,
156 CompareByWeight) -
157 items_.begin();
158 }
159
160 void ShelfModel::SetShelfItemDelegate(
161 ShelfID id,
162 std::unique_ptr<ShelfItemDelegate> item_delegate) {
163 // If another ShelfItemDelegate is already registered for |id|, we assume
164 // that this request is replacing ShelfItemDelegate for |id| with
165 // |item_delegate|.
166 RemoveShelfItemDelegate(id);
167
168 for (auto& observer : observers_)
169 observer.OnSetShelfItemDelegate(id, item_delegate.get());
170
171 id_to_item_delegate_map_[id] = std::move(item_delegate);
172 }
173
174 ShelfItemDelegate* ShelfModel::GetShelfItemDelegate(ShelfID id) {
175 if (id_to_item_delegate_map_.find(id) != id_to_item_delegate_map_.end())
176 return id_to_item_delegate_map_[id].get();
177 return nullptr;
178 }
179
180 void ShelfModel::AddObserver(ShelfModelObserver* observer) {
181 observers_.AddObserver(observer);
182 }
183
184 void ShelfModel::RemoveObserver(ShelfModelObserver* observer) {
185 observers_.RemoveObserver(observer);
186 }
187
188 int ShelfModel::ValidateInsertionIndex(ShelfItemType type, int index) const {
189 DCHECK(index >= 0 && index <= item_count() + 1);
190
191 // Clamp |index| to the allowed range for the type as determined by |weight|.
192 ShelfItem weight_dummy;
193 weight_dummy.type = type;
194 index = std::max(std::lower_bound(items_.begin(), items_.end(), weight_dummy,
195 CompareByWeight) -
196 items_.begin(),
197 static_cast<ShelfItems::difference_type>(index));
198 index = std::min(std::upper_bound(items_.begin(), items_.end(), weight_dummy,
199 CompareByWeight) -
200 items_.begin(),
201 static_cast<ShelfItems::difference_type>(index));
202
203 return index;
204 }
205
206 void ShelfModel::RemoveShelfItemDelegate(ShelfID id) {
207 if (id_to_item_delegate_map_.find(id) != id_to_item_delegate_map_.end())
208 id_to_item_delegate_map_.erase(id);
209 }
210
211 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/shelf/shelf_model.h ('k') | ash/common/shelf/shelf_model_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698