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
3 // found in the LICENSE file.
5 #include "ui/base/models/list_selection_model.h"
10 #include "base/logging.h"
15 const int ListSelectionModel::kUnselectedIndex
= -1;
17 static void IncrementFromImpl(int index
, int* value
) {
22 static bool DecrementFromImpl(int index
, int* value
) {
23 if (*value
== index
) {
24 *value
= ListSelectionModel::kUnselectedIndex
;
32 ListSelectionModel::ListSelectionModel()
33 : active_(kUnselectedIndex
),
34 anchor_(kUnselectedIndex
) {
37 ListSelectionModel::~ListSelectionModel() {
40 void ListSelectionModel::IncrementFrom(int index
) {
41 // Shift the selection to account for the newly inserted tab.
42 for (SelectedIndices::iterator i
= selected_indices_
.begin();
43 i
!= selected_indices_
.end(); ++i
) {
44 IncrementFromImpl(index
, &(*i
));
46 IncrementFromImpl(index
, &anchor_
);
47 IncrementFromImpl(index
, &active_
);
50 void ListSelectionModel::DecrementFrom(int index
) {
51 for (SelectedIndices::iterator i
= selected_indices_
.begin();
52 i
!= selected_indices_
.end(); ) {
53 if (DecrementFromImpl(index
, &(*i
)))
54 i
= selected_indices_
.erase(i
);
58 DecrementFromImpl(index
, &anchor_
);
59 DecrementFromImpl(index
, &active_
);
62 void ListSelectionModel::SetSelectedIndex(int index
) {
63 anchor_
= active_
= index
;
64 selected_indices_
.clear();
65 if (index
!= kUnselectedIndex
)
66 selected_indices_
.push_back(index
);
69 bool ListSelectionModel::IsSelected(int index
) const {
70 return std::find(selected_indices_
.begin(), selected_indices_
.end(), index
) !=
71 selected_indices_
.end();
74 void ListSelectionModel::AddIndexToSelection(int index
) {
75 if (!IsSelected(index
)) {
76 selected_indices_
.push_back(index
);
77 std::sort(selected_indices_
.begin(), selected_indices_
.end());
81 void ListSelectionModel::RemoveIndexFromSelection(int index
) {
82 SelectedIndices::iterator i
= std::find(selected_indices_
.begin(),
83 selected_indices_
.end(), index
);
84 if (i
!= selected_indices_
.end())
85 selected_indices_
.erase(i
);
88 void ListSelectionModel::SetSelectionFromAnchorTo(int index
) {
89 if (anchor_
== kUnselectedIndex
) {
90 SetSelectedIndex(index
);
92 int delta
= std::abs(index
- anchor_
);
93 SelectedIndices
new_selection(delta
+ 1, 0);
94 for (int i
= 0, min
= std::min(index
, anchor_
); i
<= delta
; ++i
)
95 new_selection
[i
] = i
+ min
;
96 selected_indices_
.swap(new_selection
);
101 void ListSelectionModel::AddSelectionFromAnchorTo(int index
) {
102 if (anchor_
== kUnselectedIndex
) {
103 SetSelectedIndex(index
);
105 for (int i
= std::min(index
, anchor_
), end
= std::max(index
, anchor_
);
108 selected_indices_
.push_back(i
);
110 std::sort(selected_indices_
.begin(), selected_indices_
.end());
115 void ListSelectionModel::Move(int from
, int to
) {
117 bool was_anchor
= from
== anchor_
;
118 bool was_active
= from
== active_
;
119 bool was_selected
= IsSelected(from
);
122 DecrementFrom(from
+ 1);
132 AddIndexToSelection(to
);
135 void ListSelectionModel::Clear() {
136 anchor_
= active_
= kUnselectedIndex
;
137 SelectedIndices empty_selection
;
138 selected_indices_
.swap(empty_selection
);
141 void ListSelectionModel::Copy(const ListSelectionModel
& source
) {
142 selected_indices_
= source
.selected_indices_
;
143 active_
= source
.active_
;
144 anchor_
= source
.anchor_
;
147 bool ListSelectionModel::Equals(const ListSelectionModel
& rhs
) const {
148 return active_
== rhs
.active() &&
149 anchor_
== rhs
.anchor() &&
150 selected_indices() == rhs
.selected_indices();